题目链接
这道题的状态转移方程比较易于确定。dp[i][j]
表示能放前i个物品的情况下,容量为j时能放物品的数量(这道题歌曲数量对应物品数量,容量对应时间)。
技巧(收获)
-
二维dp数组可以视情况优化为一维dp数组。
-
在0-1背包问题的初始化中
背包必须装满,dp[0] = 0,其他初始化为负无穷 背包可以不装满,dp全部初始化为0,有关这一点的解释。
-
在遍历时,如果是找价值最大的,从后往前遍历。
参考:https://blog.csdn.net/pegasuswang_/article/details/9131619
#include <stdio.h>
#define jinge 678
int max(int a, int b) {
return a > b ? a : b;
}
int main() {
int T, n, t;
int i, j;
scanf("%d", &T);
int song[51] = {0};
int dp[10000] = {0};
int count = 1;
while (T--) {
scanf("%d %d", &n, &t);
for (i = 1; i <= n; i++) {
scanf("%d", &song[i]);
}
for (i = 0; i <= t; i++) {
dp[i] = -1;
}
dp[0] = 0;
int ans = 0,ans_time = 0;
for (i = 1; i <= n; i++) {
for (j = t-1; j >= song[i]; j--) {
if(dp[j - song[i]] + 1>=dp[j]){
dp[j] = dp[j - song[i]] + 1;
//这里的dp[j] = dp[j - song[i]] + 1;相当于dp[i][j] = dp[i-1][j - song[i]] + 1;
}
}
}
for(j=t-1;j>0;j--)
if(dp[j]>ans){
ans = dp[j];
ans_time = j;
}
for(int i=0;i<t;i++){
printf("%3d ",dp[i]);
}
printf("Case %d: %d %d\n", count++, ans + 1, ans_time + jinge);
}
return 0;
}
/*
2
3 100
60 70 80
3 100
30 69 70
*/