求在歌曲的数目最多的情况下,花费的时间最大为多少。
单独维护最大消耗时间和最多的曲目都是普通的01背包,但是维护在曲目最多的情况下维护最大消耗时间,在更新的时候如果数目没法更新的话,在保证数目一样的情况下,更新一下最大时间消耗就可以了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 100;
int dp1[maxn][11111];
int dp2[maxn][11111];
int n, p;
int c[maxn],v[maxn];
int main()
{
int T;
cin >> T;
int kase = 1;
while(T--)
{
memset(dp1,0,sizeof(dp1));
memset(dp2,0,sizeof(dp2));
cin >> n >> p;
for(int i = 1 ; i <= n ; i++)
{
cin >> c[i];
v[i]=1;
}
p--;
for(int i = 1 ; i <= n ; i++)
{
for(int j = 0 ; j <= p ; j++)
{
if(j - c[i] < 0)
{
dp1[i][j] = dp1[i-1][j];
dp2[i][j] = dp2[i-1][j];
}
if( j - c[i] >= 0 )
{
if(dp1[i-1][j] < dp1[i-1][j-c[i]] + v[i])
{
dp1[i][j] = dp1[i-1][j-c[i]] + v[i];
dp2[i][j] = dp2[i-1][j-c[i]] + c[i];
}
else if(dp1[i-1][j] == dp1[i-1][j-c[i]] + v[i])
{
dp1[i][j] = dp1[i-1][j];
dp2[i][j] = max(dp2[i-1][j-c[i]] + c[i],dp2[i-1][j]);
}
else
{
dp1[i][j] = dp1[i-1][j];
dp2[i][j] = dp2[i-1][j];
}
}
}
}
printf("Case %d: %d %d\n",kase++,dp1[n][p] + 1, dp2[n][p] + 678);
}
return 0;
}