LightOJ1105 Fi Binary Number(数位DP)
题目要求第k个没有连续两个1的二进制数。
这算数位DP吧,只不过以前遇到的是统计区间的数字情况,而这题是求第几个数字,差不多是反过来的。
本来我想用状态dp[i][0/1]表示长度i末尾0或1的二进制数个数,发现这样好像没法解。
最后需要根据数位DP状态的值推算出要求二进制数各个位置是0还是1,这个肯定是从高位到低位确定——所以应该反过来表示状态:
dp[i][0/1]:长度i开头为0或1的二进制数个数
最后的求解:
- 先利用dp[i][1]的值确定出要求二进制的位数
- 位数知道后,最高位得是1
- 最后就从高到低根据 前一位是0还是1、dp[i][0]的值和剩下的个数的关系 一位位确定。
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 #define MAXL 100 5 int d[MAXL][2]; 6 int main(){ 7 d[0][0]=1; 8 for(int i=1; i<100; ++i){ 9 d[i][0]=d[i-1][0]+d[i-1][1]; 10 d[i][1]=d[i-1][0]; 11 } 12 int t,n; 13 scanf("%d",&t); 14 for(int cse=1; cse<=t; ++cse){ 15 scanf("%d",&n); 16 int len=1; 17 while(n>d[len][1]){ 18 n-=d[len][1]; 19 ++len; 20 } 21 printf("Case %d: 1",cse); 22 int last=1; 23 for(int i=1; i<len; ++i){ 24 if(last==1){ 25 putchar('0'); 26 last=0; 27 }else if(n>d[len-i][0]){ 28 n-=d[len-i][0]; 29 putchar('1'); 30 last=1; 31 }else{ 32 putchar('0'); 33 last=0; 34 } 35 } 36 putchar('\n'); 37 } 38 return 0; 39 }