这个题差不多算是记录路径的DP,题目很短,然后本来以为很水的。最近水过习惯了,竟然敲了个暴力,各种TLE,然后换了种方式水,还是水不过去,后台的k很大,所以O(k)的算法是不可能过的。这就开始纠结了,开始的时候有想过是不是DP问题,状态转移很容易发现,不过这个题目是求第k大的,然后尝试用DP写了写,挂在一个大数据了,不好检查,自己出了几个数据,检查出了BUG,如果确定了第i位为1之后,再更新的时候sum[i]数组,在最后一次改了int之后,终于过了!!!
1 /* 2 ID: cuizhe 3 LANG: C++ 4 TASK: kimbits 5 */ 6 #include <iostream> 7 #include <cstdio> 8 #include <cstring> 9 #include <map> 10 using namespace std; 11 long long dp[60][60],sum[50]; 12 int o[50]; 13 int main() 14 { 15 int i,j,z; 16 long long n,m,k; 17 freopen("kimbits.in","r",stdin); 18 freopen("kimbits.out","w",stdout); 19 scanf("%lld%lld%lld",&n,&m,&k); 20 dp[1][1] = 1; 21 dp[1][0] = 1; 22 for(i = 2; i <= n; i ++)//状态转移 23 { 24 dp[i][0] = dp[i-1][0]; 25 for(j = 1; j <= i&&j <= m; j ++) 26 { 27 dp[i][j] += dp[i-1][j];//第i位是0 28 dp[i][j] += dp[i-1][j-1];//第i位是1 29 } 30 } 31 z = 1; 32 while(k&&z) 33 { 34 memset(sum,0,sizeof(sum)); 35 if(k == 1) 36 { 37 break; 38 } 39 for(i = 1; i <= n; i ++)//这里写的效率不是很高,DP的复杂度很小就无所谓了。 40 { 41 for(j = 0; j <= i&&j <= m; j ++) 42 sum[i] += dp[i][j]; 43 } 44 for(i = n; i >= 1; i --) 45 { 46 if(k > sum[i]) 47 { 48 o[i+1] = 1; 49 k -= sum[i]; 50 m --; 51 break; 52 } 53 else if(k == sum[i]) 54 { 55 for(j = i; j >= i-m+1&&j >= 1; j --) 56 o[j] = 1; 57 z = 0; 58 break; 59 } 60 } 61 } 62 for(i = n; i >= 1; i --) 63 printf("%d",o[i]); 64 printf("\n"); 65 return 0; 66 }