描述
需对容量为c 的背包进行装载。从n个物品中选取装入背包的物品,每件物品i的重量为wi
,价值为pi。对于可行的背包装载,背包中物品的总重量不能超过背包的容量,
最佳装载是指所装入的物品价值最高。
输入
多个测例,每个测例的输入占三行。
第一行两个整数:n(n<=10)和c,第二行n个整数分别是w1到wn,
第三行n个整数分别是p1到pn。
n 和 c 都等于零标志输入结束。
输出
每个测例的输出占一行,输出一个整数,即最佳装载的总价值。
样例
输入样例
1 2
1
1
2 3
2 2
3 4
0 0
输出样例
1
4
透露一点系统测试用数据
标准输入
1 0
2
3
1 2
1
1
2 3
2 2
3 4
2 8
9 7
7 9
2 5
2 2
10 2
10 100
4 5 6 6 7 7 8 9 11 45
7 9 11 12 13 14 15 17 21 89
0 1
0 0
标准输出
0
1
4
9
12
193
0
上代码
#include <iostream>
using namespace std;
int weight[11];
int price[11];
int dp[11][1000];
int n, c;
int outmax(int a, int b) { return (a > b ? a : b); }
int main() {
int i, j;
while (1) {
cin >> n >> c;
if (!n && !c) {
return 0;
}
for (i = 1; i <= n; i++) {
cin >> weight[i];
}
for (i = 1; i <= n; i++) {
cin >> price[i];
}
for (i = 0; i <= n; i++) {
for (j = 0; j <= c; j++) {
if (!i || !j) {
dp[i][j] = 0;
} else if (weight[i] > j) {
dp[i][j] = dp[i - 1][j];
} else {
dp[i][j] = outmax(dp[i - 1][j],
dp[i - 1][j - weight[i]] + price[i]);
}
}
}
cout << dp[n][c] << endl;
}
}
这里用的还是二维数组构建,下面进行优化,由动态规划的无后效性,每次算第 i 行的时候只要知道第 i - 1 行的结果,所以优化为一维数组,节约空间复杂度。
优化的时候注意,如果正序遍历,后面使用到“上一行”的数据就是被覆盖的,会导致运算出错,所以改为逆序遍历。
#include <iostream>
using namespace std;
int weight[11];
int price[11];
int n, c;
int outmax(int a, int b) { return (a > b ? a : b); }
int main() {
int i, j;
while (1) {
int dp[1000] = {0};
cin >> n >> c;
if (!n && !c) {
return 0;
}
for (i = 1; i <= n; i++) {
cin >> weight[i];
}
for (i = 1; i <= n; i++) {
cin >> price[i];
}
for (i = 1; i <= n; i++) {
for (j = c; j >= weight[i]; j--) {
//这里需要逆序
dp[j] = outmax(dp[j], dp[j - weight[i]] + price[i]);
}
}
cout << dp[c] << endl;
}
}