USACO 3.2 Stringsobits(DP)

这个题差不多算是记录路径的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 }

 

posted @ 2012-11-19 21:16  Naix_x  阅读(231)  评论(0编辑  收藏  举报