C++ 实现 0-1 背包问题:最大价值求解
C++ 实现 0-1 背包问题:最大价值求解
问题描述:
给定 n 种物品(每种仅一个)和一个容量为 c 的背包,要求选择物品装入背包,使得装入背包中物品的总价值最大。
输入格式:
测试数据有多组,处理到文件尾。每组测试数据输入 3 行,
- 第 1 行为两个整数 n (1 ≤ n ≤ 400) 和 c (1 ≤ c ≤ 1500),分别表示物品数量与背包容量,
- 第二行为 n 个物品的重量 w[i] (1 ≤ i ≤ n),
- 第三行为这 n 个物品的价值 v[i] (1 ≤ i ≤ n)。物品重量、价值都为整数。
输出格式:
对于每组测试,在一行上输出一个整数,表示装入背包的最大总价值(结果保证在 2^31 - 1 范围内)。
输入样例:
4 9
2 3 4 5
3 4 5 7
25 100
42 6 48 13 38 124 8 17 41 25 41 26 47 41 171 25 7 30 35 7 17 32 45 27 38
49 19 53 40 22 4 36 20 49 25 61 48 67 34 57 52 46 45 33 41 20 38 34 58 63
输出样例:
12
292
思路:
0-1 背包问题,用 DP 求解。dp[i][j] 表示前 i 个物品重量不超过 j 的最大价值。
状态转移方程:dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i])。
C++ 代码:
#include <iostream>
using namespace std;
int main() {
int n, c;
while (cin >> n >> c) {
int w[401], v[401];
for (int i = 1; i <= n; i++) {
cin >> w[i];
}
for (int i = 1; i <= n; i++) {
cin >> v[i];
}
int dp[401][1501] = {0};
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= c; j++) {
if (j >= w[i]) {
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]);
} else {
dp[i][j] = dp[i - 1][j];
}
}
}
cout << dp[n][c] << endl;
}
return 0;
}
解释:
dp[i][j]数组存储了前i个物品重量不超过j的最大价值。- 初始化
dp[0][j]为 0,表示没有物品时价值为 0。 - 在循环中,对于每个物品
i和背包容量j,我们根据状态转移方程判断是否选取当前物品。 - 如果
j大于等于当前物品的重量w[i],则可以选择将当前物品放入背包,此时最大价值为dp[i-1][j-w[i]] + v[i],即前i-1个物品在剩余容量j-w[i]下的最大价值加上当前物品的价值。 - 如果
j小于当前物品的重量w[i],则不能将当前物品放入背包,此时最大价值等于前i-1个物品在容量j下的最大价值,即dp[i-1][j]。 - 最终
dp[n][c]即为所有物品在背包容量c下的最大价值。
原文地址: https://www.cveoy.top/t/topic/ohJ4 著作权归作者所有。请勿转载和采集!