问题描述:给定一组物品,每个物品有重量和价值,如何选择物品放入容量为 W 的背包中,使得背包内物品的总价值最大?每个物品只能使用一次(0-1 选择)。
10
预设:背包最大承重为 10
使用这 3 件物品和容量 10 的背包,演示 0-1 背包动态规划的求解过程。
| 物品/容量 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|---|
最终容量使用:0/10
最终总价值:0
状态定义:dp[i][j] 表示「只考虑前 i 个物品,在背包容量为 j 时能取得的最大总价值」。
状态转移方程:
如果第 i 个物品重量为 weight[i],价值为 value[i]:
1. 如果 j < weight[i](装不下第 i 个物品):
dp[i][j] = dp[i-1][j]
2. 如果 j ≥ weight[i](可以考虑装):
dp[i][j] = max( dp[i-1][j], dp[i-1][j - weight[i]] + value[i] )
/* 0-1 背包动态规划伪代码 */
function knapsack01(weights, values, capacity) {
const n = weights.length;
const dp = new Array(n + 1).fill().map(
() => new Array(capacity + 1).fill(0)
);
for (let i = 1; i <= n; i++) {
for (let j = 0; j <= capacity; j++) {
if (j >= weights[i-1]) {
dp[i][j] = Math.max(
dp[i-1][j],
dp[i-1][j - weights[i-1]] + values[i-1]
);
} else {
dp[i][j] = dp[i-1][j];
}
}
}
return dp[n][capacity];
}