有n 个物品,它们有各自的重量和价值,现有给定容量的背包,如何让背包里装入的物品具有最大的价值总和?
规划方向:d[i][j]表示把前i个物品装到容量为j的背包中的最大总重量
#define INF 100
#include<algorithm>
#include<iostream>
using namespace std;
int c = 10,n=3; //c是体积
int d[INF][INF]; // maxw[s]代表此体积能装的最大重量
int v[3] = { 1,3,5 };
int w[3] = { 1,7,8 };
int main()
{
memset(d, -INF, sizeof(d));
int i, j;
for (i = 0; i < n; i++) { //d[i][j] 把前i个物品装到容量为j的背包的最大总重量
for (j = 0; j <= c; j++) {
d[i][j] = (i == 0 ? 0 : d[i - 1][j]); //先不装第i个物品,还剩j容量时,等于d[i - 1][j]
if (j >= v[i]) {
d[i][j] = max(d[i][j], d[i - 1][j - v[i]] +w[i]); //判断装了第i个物品会不会更大
}
}
}
cout <<"能装的最大重量为:"<< d[n-1][c] <<endl;
return 0;
}
此种方法,打印时不太方便,不能保证字典序最小
结果
读入时可以边读边计算
#define INF 100
#include<algorithm>
#include<iostream>
using namespace std;
int c = 10,n=3; //c是体积
int d[INF][INF]; // maxw[s]代表此体积能装的最大重量
//int v[3] = { 1,3,5 };
//int w[3] = { 1,7,8 };
int main()
{
memset(d, -INF, sizeof(d));
int i, j,v,w;
for (i = 0; i < n; i++) { //d[i][j] 把前i个物品装到容量为j的背包的最大总重量
cin >> v >> w;
for (j = 0; j <= c; j++) {
d[i][j] = (i == 0 ? 0 : d[i - 1][j]); //先不装第i个物品,还剩j容量时,等于d[i - 1][j]
if (j >= v) {
d[i][j] = max(d[i][j], d[i - 1][j - v] +w); //判断装了第i个物品会不会更大
}
}
}
cout <<"能装的最大重量为:"<< d[n-1][c] <<endl;
return 0;
}
结果:
还可以将d变成滚动数组,由二维变成一维
#include<iostream>
using namespace std;
int c = 6,n=3; //c是体积
int d[INF]; //代表此体积能装的最大重量
//int v[3] = { 1,3,5 };
//int w[3] = { 4,9,10 };
int main()
{
memset(d, 0, sizeof(d));
int i, j,v,w;
for (i = 0; i < n; i++) { //d[i][j] 把前i个物品装到容量为j的背包的最大总重量
cin >> v >> w;
for (j = c; j >= 0; j--) {
if (j >= v) {
d[j] = max(d[j], d[j - v] +w); //因为i递增,所以d[j]其实是d[i-1][j]已经算出的
} //把max(d[i-1][j],d[i-1][j-v])保存在f[j]中,覆盖掉原来的f[i-1][j]
}
}
cout <<"能装的最大重量为:"<< d[c] <<endl;
return 0;
}
结果: