文章转载自
读这篇文章之前,建议先读一下链接博主的文章,我刚开始看没有太理解,后来发现博主写的不错,然后又写了一些当时不太懂得地方。所有引用都是博主所写
- 第一个解释:
这是题的几个重要信息
Vi表示第 i 个物品的价值,Wi表示第 i 个物品的体积,定义V(i,j):当前背包容量 j,前 i 个物品最佳组合对应的价值,
这个表格其实代表的是代码中的dp[i][j],**当前背包容量 j,**当时怎么也理解不了这个地方,
我以为这个包一开始就假设它的体积就是8,在前i个物品中组合,组合出最优解后包的体积还剩j,
所以说dp[4][8]=10,我就不大理解了,认为应该是 dp[4][0]=10,就是一共四种物品,从其中选了几种后组成最优解,当前包的体积还有0,后来再一想,dp是子问题求解,
想起老师画的图
所以先是想包有1这么大,他的最优解是几,然后再想包有2那么大,他的最优解是甚么,一直求到包的体积是8
#include<iostream>
using namespace std;
#include <algorithm>
int w[5] = { 0 , 2 , 3 , 4 , 5 }; //商品的体积2、3、4、5
int v[5] = { 0 , 3 , 4 , 5 , 6 }; //商品的价值3、4、5、6
int bagV = 8; //背包大小
int dp[5][9] = { { 0 } }; //动态规划表
int item[5]; //最优解情况
void findMax() { //动态规划
for (int i = 1; i <= 4; i++) {//四个物品
for (int j = 1; j <= bagV; j++) {//例如当i是1时,,表示只有编号为1的物品,
//当体积是j时的最优解
if (j < w[i])
dp[i][j] = dp[i - 1][j];
else
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]);
}
}
}
void findWhat(int i, int j) { //最优解情况i是物品总的种类,j是包的体积
if (i >= 0) {
if (dp[i][j] == dp[i - 1][j]) {//如果编号为i的没有放进去,就item[i]=0;
item[i] = 0;
findWhat(i - 1, j);
}
else if (j - w[i] >= 0 && dp[i][j] == dp[i - 1][j - w[i]] + v[i]) {
item[i] = 1;//说明他在 最优解中
findWhat(i - 1, j - w[i]);
}
}
}
void print() {
for (int i = 0; i < 5; i++) { //动态规划表输出
for (int j = 0; j < 9; j++) {
cout << dp[i][j] << ' ';
}
cout << endl;
}
cout << endl;
for (int i = 0; i < 5; i++) //最优解输出
cout << item[i] << ' ';
cout << endl;
}
int main()
{
findMax();
findWhat(4, 8);
print();//动态规划表输出
return 0;
}//