题目地址:Ural 1081
先用dp求出每个长度下的合法序列(开头为1)的个数。然后求前缀和。会发现正好是一个斐波那契数列。然后每次判断是否大于此时长度下的最少个数,若大于,说明这一位肯定是1,若小于,则肯定是0.就这样不断输出出来即可。
代码如下:
#include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include <ctype.h> #include <queue> #include <map> #include <set> #include <algorithm> using namespace std; #define LL __int64 const int INF=0x3f3f3f3f; LL dp[3][50], sum[50], s[50]; int main() { int i, j, n, k; memset(dp,0,sizeof(dp)); dp[0][1]=0; dp[1][1]=1; sum[1]=2; s[1]=2; for(i=2; i<44; i++) { dp[1][i]+=dp[0][i-1]; dp[0][i]+=dp[0][i-1]+dp[1][i-1]; sum[i]=dp[0][i]+dp[1][i]; s[i]=s[i-1]+sum[i]; } /*for(i=1;i<=44;i++) { printf("%d ",s[i]); } puts("");*/ s[0]=1; while(scanf("%d%d",&n,&k)!=EOF) { if(k>s[n]) printf("-1\n"); else { while(n--) { if(k>s[n]) { printf("1"); k-=s[n]; } else printf("0"); } } } return 0; }
时间: 2024-10-22 22:49:29