UVa 12563 Jin Ge Jin Qu hao【01背包】

题意:给出t秒时间,n首歌分别的时间a[i],还给出一首长度为678的必须唱的劲歌金曲,问最多能够唱多少首歌(只要最后时间还剩余一秒,都可以将劲歌金曲唱完)

用dp[i]代表花费i时间时唱的歌的最大数量 背包容量即为给出的总时间t-1(留一秒钟唱劲歌金曲)

,每首歌的代价为a[i], 然后状态转移方程为

dp[j]=max(dp[j],dp[j-a[i]]+1);

 

自己写的时候,一直一直wa 后来看了lrj的代码,发现是初始化不对, 改掉初始化就对了= =

可是为什么要这样初始化呢= =

后来才明白,给初始状态赋特殊的值,是因为这个状态是不合法的,不能从这个状态开始转移 比如说如果初始值都赋为0的话,dp[99]=0,那么就是一首歌都还没有唱,就已经花费了99秒钟,

所以应该初始化为-1(-2,-3,-4-5,-6,-7-------等其他取不到的特殊值)

 1 #include<iostream>  

 2 #include<cstdio>  

 3 #include<cstring> 

 4 #include <cmath> 

 5 #include<stack>

 6 #include<vector>

 7 #include<map> 

 8 #include<set>

 9 #include<queue> 

10 #include<algorithm>  

11 #define mod=1e9+7;

12 using namespace std;

13 

14 typedef long long LL;

15 const int maxn=100005;

16 int a[maxn],dp[maxn];

17 

18 int main(){

19     int n,t,i,j,ncase,kase=0;

20     cin>>ncase;

21     while(ncase--){

22         

23         cin>>n>>t;

24         for(i=1;i<=n;i++) cin>>a[i];

25         

26         int ans=0;

27         

28         for(int i = 0; i < t; i++) dp[i] = -1;

29         dp[0] = 0;

30         

31         for(i=1;i<=n;i++){

32             for(j=t-1;j>=0;j--){

33                 if(j>=a[i]) dp[j]=max(dp[j],dp[j-a[i]]+1);

34                 

35                 ans=max(ans,dp[j]);    

36             //    printf("ans=%d\n",ans);

37             //    printf("dp[%d]=%d\n",j,dp[j]);            

38             }

39         }

40         

41         for(i=t-1;i>=0;i--){

42             if(dp[i]==ans){

43                 printf("Case %d: %d %d\n", ++kase, ans + 1, i + 678);

44                 break;

45             }

46         }

47     }

48     return 0;    

49 }
View Code

 

你可能感兴趣的:(uva)