标签:
题意:给出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 }
UVa 12563 Jin Ge Jin Qu hao【01背包】
标签:
原文地址:http://www.cnblogs.com/wuyuewoniu/p/4376037.html