01背包动态规划法
01背包动态规划法
思路
二维数组记录每次的选择,i行为物品,j列为体积
当选择1号物品时,体积从1-max;
再选择2号,以此类推。
如果选择当前物品的体积大于背包剩余容量,则选择之前的物品dp[i][j] = dp[i - 1][j];
如果选择当前物品的体积小于背包剩余容量,则在选择当前物品和不选择当前物品两个结果中,选择一个价值最大值dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]);
dp[i - 1][j - w[i]] + v[i]为选择了当前物品,选择当前物品为选择上一个物品+当前物品。
代码实现
#include<iostream>
using namespace std;
int w[333] = { 0 }; //商品的体积
int v[333] = { 0 }; //商品的价值
int m,n; //m背包大小,n商品数量
int dp[222][222] = { { 0 } }; //动态规划表
int item[2222]; //选择了哪个商品
void findMax() { //动态规划
for (int i = 1; i <=n; i++) {
for (int j = 1; j <= m; 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) { //最优解情况
if (i >= 0) {
if (dp[i][j] == dp[i - 1][j]) {
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() {
int x = 0;
for (int i = 1; i <= n; i++) { //动态规划表输出
for (int j = 1; j <= m; j++) {
if (dp[i][j] > x)
x = dp[i][j];
}
}
cout << "最大价值为:";
cout << x;
cout << endl;
cout << "选择的物品为:";
for (int i = 1; i <= n; i++)
{
if (item[i] == 1)
cout << i << " ";
}
cout << endl;
}
void init() {
int i;
cin >> m >> n;
for (i = 1; i <= n; i++) {
cin >> w[i] >> v[i];
}
}
int main()
{
init();
findMax();
findWhat(n, m);
print();
return 0;
}

浙公网安备 33010602011771号