1 条题解
-
0
这是一道关于排列组合和查找的问题,解题的关键在于生成所有可能的可爱栅栏排列,并根据目录编号找到对应的排列。
算法标签
排列组合、查找算法
题解思路
生成所有排列:使用 itertools.permutations 函数生成所有长度为 的数字排列。 筛选可爱栅栏排列:定义 is_cute_permutation 函数,检查每个排列是否满足可爱栅栏的条件,即每个中间木板的高度要么大于相邻木板,要么小于相邻木板。 排序可爱栅栏排列:将筛选出的可爱栅栏排列按照题目规定的顺序进行排序。 查找对应排列:根据给定的目录编号 ,在排序后的可爱栅栏排列中找到对应的排列。
代码实现(c++)
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; int N; ll C; ll dp[21][21][2]; bool used[21]; int res[21]; int main(){ int Num; scanf("%d", &Num); dp[1][1][1] = dp[1][1][0] = 1; for(int i = 2; i <= 20; i ++){ for(int j = 1; j<= i; j ++){ for(int k = j; k <= i; k ++){ dp[i][j][1] += dp[i - 1][k][0]; } for(int k = j - 1; k >= 1; k --){ dp[i][j][0] += dp[i - 1][k][1]; } } } for(int num =0; num < Num; num ++){ scanf("%d %lld", &N, &C); memset(used, 0, sizeof(used)); ll skipped = 0; for(int i = 1; i <= N; i ++){ ll old_val = skipped; int No = 0; for(int j = 1; j <= N; j ++){ old_val = skipped; if(!used[j]){ No ++; if(i == 1){ skipped += (dp[N][No][0] + dp[N][No][1]); } else { if(j > res[i - 1] && (i <= 2 || res[i - 2] > res[i - 1])){ skipped += dp[N - i + 1][No][0]; } if(j < res[i - 1] && (i <= 2 || res[i - 2] < res[i - 1])){ skipped += dp[N - i + 1][No][1]; } } if(skipped >= C){ res[i] = j; used[j] = true; skipped = old_val; break; } } } } for(int i = 1; i <= N; i ++){ printf("%d ", res[i]); } printf("\n"); } }
- 1
信息
- ID
- 38
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者