背包问题详解
1. 问题描述
有一个容量为V的背包,还有n个物体。现在忽略物体实际几何形状,我们认为只要背包的剩余容量大于等于物体体积,那就可以装进背包里。每个物体都有两个属性,即体积w和价值v。
问:如何向背包装物体才能使背包中物体的总价值最大?
C++代码
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
int w[5] = {0, 2, 3, 4, 7}; // 商品的体积2、3、4、7
int v[5] = {0, 1, 3, 5, 9}; // 商品的价值1、3、5、9
int bagV = 10; // 背包大小
int dp[5][11] = {{0}}; // 动态规划表
vector<int> selectedItems; // 用于记录选择的物品
for (int i = 1; i <= 4; i++) {
for (int j = 1; j <= bagV; 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]);
}
}
// 输出动态规划表
cout << "规划表" << endl;
for (int i = 0; i < 5; i++) {
for (int j = 0; j <= bagV; j++) {
cout << dp[i][j] << ' ';
}
cout << endl;
}
// 输出背包中物品的最大总价值
cout << "背包中物品的最大总价值为:" << dp[4][bagV] << endl;
// 追踪解的过程
int remainingCapacity = bagV;
for (int i = 4; i >= 1; i--) {
if (dp[i][remainingCapacity] != dp[i - 1][remainingCapacity]) {
selectedItems.push_back(i);
remainingCapacity -= w[i];
}
}
// 输出追踪解的过程
cout << "追踪解的过程:" << endl;
for (int i = selectedItems.size() - 1; i >= 0; i--) {
cout << "选择物品:" << selectedItems[i] << endl;
}
return 0;
}
运行结果