比较简单的01背包问题。
输入的n最大为50, 而且n + 1首歌长度大于t,即t最大为 50 * 3 * 60 + 678。
接下来就可以DP了。
#include <iostream>
#include <cstring>
using namespace std;
const int maxn = 50 + 5;
const int maxv = 10000;
int m[maxn];
int dp[maxv], dp_n[maxv], dp_t[maxn][maxv];
int main() {
int T, Case(0);
cin >> T;
while(T--) {
memset(m, 0, sizeof(m));
memset(dp, 0, sizeof(dp));
memset(dp_t, 0, sizeof(dp_t));
memset(dp_n, 0, sizeof(dp_n));
int n, t;
int best_t(0), max_n(0);
cin >> n >> t;
for(int i = 0; i < n; i++) {
cin >> m[i];
}
for(int i = 0; i < n; ++i) {
for(int j = t - 1; j >= 0; --j) {
if(j - m[i] == 0) {
dp[j] = 1;
max_n = max(max_n, dp[j]);
} else if(j - m[i] != 0 && dp[j - m[i]]) {
dp[j] = max(dp[j], dp[j - m[i]] + 1);
max_n = max(max_n, dp[j]);
}
}
}
cout << "Case " << ++Case << ": ";
for(int j = t - 1; j >= 0; --j) {
if(dp[j] == max_n && dp[j] != 0) {
best_t = j;
break;
}
}
cout << max_n + 1 << " " << best_t + 678 << endl;
}
return 0;
}