USACO3.22Stringsobits
DP预处理出来 i位不超过j的个数 然后再进行从小到大找第一个比I大的 然后用I减掉上一个比I小的 剩余的按照之前的方法循环找 知道剩余为0
细节挺繁琐的 对照数据改了又改 最后一组数据还超 了int。。
1 /* 2 ID: shangca2 3 LANG: C++ 4 TASK: kimbits 5 */ 6 #include <iostream> 7 #include<cstdio> 8 #include<cstring> 9 #include<algorithm> 10 #include<stdlib.h> 11 using namespace std; 12 #define LL long long 13 LL dp[32][32],kk[32]; 14 void init() 15 { 16 int i,j; 17 for(i = 1; i <= 31 ; i++) 18 dp[i][0] = 1; 19 for(i = 1; i <= 31 ; i++) 20 { 21 for(j = 1; j < i ; j++) 22 dp[i][j] = dp[i-1][j-1]+dp[i-1][j]; 23 dp[i][i] = dp[i][i-1]+1; 24 } 25 } 26 int main() 27 { 28 freopen("kimbits.in","r",stdin); 29 freopen("kimbits.out","w",stdout); 30 int i,j,n,o,l,g; 31 LL ss,k; 32 init(); 33 while(scanf("%d%d%lld",&n,&l,&k)!=EOF) 34 { 35 memset(kk,0,sizeof(kk)); 36 g=0; 37 while(dp[l][l]>k) 38 { 39 l--; 40 } 41 for(i = 1; i <= n ;i++) 42 { 43 if(dp[i][l]>=k) 44 { 45 o = i; 46 if(k==dp[i][l]) 47 { 48 for(g = i ; g >= i-l+1 ; g--) 49 kk[g] = 1; 50 break; 51 } 52 ss = k-dp[i-1][l]; 53 kk[i] = 1; 54 l--; 55 while(ss) 56 { 57 if(dp[l][l]>ss) 58 { 59 l--; 60 continue; 61 } 62 for(j = 1; j <= n ;j++) 63 if(dp[j][l]>=ss) 64 { 65 if(ss==dp[j][l]) 66 { 67 for(g = j ; g >= j-l+1 ; g--) 68 kk[g] = 1; 69 ss=0; 70 break; 71 } 72 ss-=dp[j-1][l]; 73 kk[j] = 1; 74 l--; 75 break; 76 } 77 if(ss==0) 78 break; 79 } 80 break; 81 } 82 } 83 for(i = n ; i>=1 ; i--) 84 printf("%d",kk[i]); 85 puts(""); 86 } 87 return 0; 88 }