题目链接:https://vjudge.net/problem/UVA-12563
题意:n首歌要在m-1的时间内挑k首唱,现在希望在k尽可能大的情况下,时间尽可能长地唱。问最后最大k+1多大,最长时间+678多长。
普通完全背包,附加额外记一维记录歌曲个数。先判断当个数相同的时候,仅更新时长,否则两个都更新。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 55; 5 const int maxm = 11000; 6 int n, m, p; 7 int w[maxn], f[maxn][maxm][2]; 8 9 10 signed main() { 11 // freopen("in", "r", stdin); 12 // freopen("out", "w", stdout); 13 int T, _ = 1; 14 scanf("%d", &T); 15 while(T--) { 16 scanf("%d%d",&n,&m); 17 for(int i = 1; i <= n; i++) scanf("%d", &w[i]); 18 m--; 19 memset(f, 0, sizeof(f)); 20 for(int i = 1; i <= n; i++) { 21 for(int j = 0; j <= m; j++) { 22 f[i][j][0] = f[i-1][j][0]; 23 f[i][j][1] = f[i-1][j][1]; 24 if(j >= w[i]) { 25 if(f[i][j][1] == f[i-1][j-w[i]][1] + 1) { 26 f[i][j][0] = max(f[i][j][0], f[i-1][j-w[i]][0]+w[i]); 27 } 28 else if(f[i][j][1] < f[i-1][j-w[i]][1] + 1) { 29 f[i][j][1] = f[i-1][j-w[i]][1] + 1; 30 f[i][j][0] = f[i-1][j-w[i]][0] + w[i]; 31 } 32 } 33 } 34 } 35 printf("Case %d: %d %d ", _++, f[n][m][1]+1, 678+f[n][m][0]); 36 } 37 return 0; 38 }