题意: 给个你一个n,为你要构造的字符串长度, 字符串相邻的两位不能同时为1。求出n位的按字典序排列第k个字符串。
think: 首先写个dp理所应当, 有的大佬构造的是一维的(其实就是fib数列), 我第一反应就是以0结尾和以1结尾的dp...
然后那么问题就来了,在构造字符串的时候我是怎么也想不通的。。。这两天就一直在想,今天起床思路一闪, 这个dp代表的完全可以是以1开头或以0开头的方案书【从左到右】,而且转移方程也完全不用改变。
dp[i][0] = dp[i-1][0] + dp[i-1][1];
dp[i][1] = dp[i-1][0]; i<=44
代码:
#include <bits/stdc++.h>
#define ll long long
#define ms(x) memset(x, 0, sizeof(x))
#define inf 0x3f3f3f3f
#define mf(x) memset(x, inf, sizeof(x))
using namespace std;
const int N = 55;
ll dp[N][3];
void init(){
ms(dp);
dp[1][0] = 1;
dp[1][1] = 1;
for(int i=2;i<=44;i++){
dp[i][0] = dp[i-1][1] + dp[i-1][0];
dp[i][1] = dp[i-1][0];
}
}
int main()
{
init();
int n;
ll tp;
scanf("%d%lld", &n, &tp);
if(tp > dp[n][1] + dp[n][0]){
puts("-1");
return 0;
}
for(int i=n;i>=1;i--){
if(tp<=dp[i][0]){
printf("0");
// tp -= dp[i][0];
}
else{
printf("1");
tp -= (dp[i][0]);
}
}
return 0;
}