题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4008
解法:单存的01背包,以时间总长t-1(因为比需要要唱劲歌金曲),然后歌曲的个数为价值,时长为重量跑01背包即可。
AC:
#include <string>
#include <string.h>
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include <string.h>
#include<stdio.h>
#include<algorithm>
#include<iostream>
const int maxn=100000;
using namespace std;
using namespace std;
int dp[maxn],a[maxn];
int main()
{
int t;
scanf("%d",&t);
for(int tcase=1;tcase<=t;tcase++)
{
int n,v,ans,maxv;
scanf("%d%d",&n,&v);
for(int i=0;i<=v;i++)
{
dp[i]=-1000000;
}
dp[0]=0;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
for(int i=0;i<n;i++)
{
for(int j=v-1;j>=a[i];j--)
{
if(dp[j]<dp[j-a[i]]+1) dp[j]=dp[j-a[i]]+1;
}
}
int main()
{
int t;
scanf("%d",&t);
for(int tcase=1;tcase<=t;tcase++)
{
int n,v,ans,maxv;
scanf("%d%d",&n,&v);
for(int i=0;i<=v;i++)
{
dp[i]=-1000000;
}
dp[0]=0;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
for(int i=0;i<n;i++)
{
for(int j=v-1;j>=a[i];j--)
{
if(dp[j]<dp[j-a[i]]+1) dp[j]=dp[j-a[i]]+1;
}
}
for(int j=v-1;j>=0;j--)
{
if(j==v-1) ans=v-1,maxv=dp[v-1];
else
{
if(dp[j]>dp[ans]) ans=j,maxv=dp[j];
}
}
printf("Case %d: %d %d\n",tcase,maxv+1,ans+678);
}
}
{
if(j==v-1) ans=v-1,maxv=dp[v-1];
else
{
if(dp[j]>dp[ans]) ans=j,maxv=dp[j];
}
}
printf("Case %d: %d %d\n",tcase,maxv+1,ans+678);
}
}