题意:求n的排列中第k个波浪形的排列
牛客巅峰赛系列里面少有的,还算有一点意思的题目(没错我就是在喷),可惜考场上时间不太够,想出来没码完(好吧确实是因为我一开始把找第k个的部分写麻烦了)。
首先来考虑求满足条件序列数量的问题,记表示长度为n,以k开头的先上升或先下降的序列数量。
预处理出来这个dp数组之后,按照跟dp相同的思路逐位确定最终答案即可。
#define ll long long
class Solution {
public:
/**
*
* @param n int整型 木棒的个数
* @param k long长整型 第k个排列
* @return int整型vector
*/
ll dp[30][30][2];
vector<int> ask(int n, int now, ll k, int flag){
vector<int> res, _res;
if (n>1){
if (flag == 0){
for (int j = 1; j < now; j++){
long long tmp = dp[n-1][j][1];
if (k > tmp) k-=tmp;else{
res = ask(n-1, j, k, 1);
break;
}
}
}else{
for (int j = now+1; j <= n; j++){
long long tmp = dp[n-1][j-1][0];
if (k > tmp) k-=tmp;else{
res = ask(n-1, j-1, k, 0);
break;
}
}
}
}
for (int i = 0; i < n-1; i++) res[i] += res[i] >= now;
_res.push_back(now);
for (int i = 0; i < n-1; i++) _res.push_back(res[i]);
return _res;
}
vector<int> stick(int n, ll k) {
memset(dp, 0, sizeof(dp));
dp[1][1][0] = dp[1][1][1] = 1;
for (int i = 2; i <= n; i++){
for (int j = 1; j <= i; j++){
for (int k = 1; k < j; k++){
dp[i][j][0] += dp[i-1][k][1];
}
for (int k = j+1; k <= i; k++){
dp[i][j][1] += dp[i-1][k-1][0];
}
}
}
for (int a = 1; a <= n; a++){
if (dp[n][a][0] >= k){
return ask(n, a, k, 0);
}else k-=dp[n][a][0];
if (dp[n][a][1] >= k){
return ask(n, a, k, 1);
}else k-=dp[n][a][1];
}
}
};
京公网安备 11010502036488号