uva12563 Jin Ge Jin Qu hao
题目大意:
KTV里面有n首歌曲你可以选择,每首歌曲的时长都给出了. 对于每首歌曲,你最多只能唱1遍. 现在给你一个时间限制t (t<=10^9) , 问你在最多t-1秒的时间内可以唱多少首歌曲num , 且最长唱歌时间是多少time (time必须<=t-1) ? 最终输出num+1 和 time+678 即可.
注意: 你需要优先让歌曲数目最大的情况下,再去选择总时长最长的.
/* 两个01背包。 两个背包大小都为180*n+678,其中一个背包存歌曲数目,另一个存歌曲总长度 对于劲歌金曲,我们可以把他看成一首体积为1s,价值为678的物品,由于优势显著,所以必选 */ #include<iostream> #include<cstdio> #include<cstring> using namespace std; int Case,t,n,m,dp[10010],ti[10010],w[60]; int main(){ //freopen("Cola.txt","r",stdin); scanf("%d",&t); while(t--){ Case++; scanf("%d%d",&n,&m); memset(dp,0,sizeof(dp)); memset(ti,0,sizeof(ti)); for(int i=1;i<=n;i++)scanf("%d",&w[i]); for(int i=1;i<=n;i++){ for(int j=m-1;j>=w[i];j--){ if((dp[j-w[i]]+1>dp[j])||(dp[j-w[i]]+1==dp[j]&&ti[j-w[i]]+w[i]>ti[j])){ dp[j]=dp[j-w[i]]+1; ti[j]=ti[j-w[i]]+w[i]; } } } int ans1=dp[m-1],ans2=ti[m-1]; printf("Case %d: %d %d\n",Case,ans1+1,ans2+678); } }