0-1背包问题
大约 1 分钟
0-1背包问题
给你一个可装载重量为 W
的背包和 N
个物品,每个物品有重量和价值两个属性。其中第 i
个物品的重量为 wt[i]
,价值为 val[i]
。现在让你用这个背包装物品,每个物品只能用一次
,在不超过被包容量的前提下,最多能装的价值是多少?
N = 3, W = 4
wt = [2, 1, 3]
val = [4, 2, 3]
dp[i][w]
定义
明确dp[i][w]
的定义如下:对于前 i
个物品,当前背包的容量为 w,这种情况下可以装的最大价值是 dp[i][w]
。
装 vs 不装
如果你没有把这第 i 个物品装入背包,那么很显然,最大价值 dp[i][w]
应该等于 dp[i-1][w]
,继承之前的结果。
如果你把这第 i 个物品装入了背包,那么 dp[i][w]
应该等于 val[i-1] + dp[i-1][w - wt[i-1]]
。
代码实现
/**
* @param {number} W
* @param {number} N
* @param {number[]} wt
* @param {number[]} val
* @return {number}
*/
var knapsack = function(W, N, wt, val) {
assert(N == wt.length);
// 已初始化的base case
var dp = new Array(N + 1).fill(0).map(() => new Array(W + 1).fill(0));
for (var i = 1; i <= N; i++) {
for (var w = 1; w <= W; w++) {
if (w - wt[i - 1] < 0) {
// 这种情况下只能选择不装入背包
dp[i][w] = dp[i - 1][w];
} else {
// 装入或者不装入背包,择优
dp[i][w] = Math.max(
dp[i - 1][w - wt[i-1]] + val[i-1],
dp[i - 1][w]
);
}
}
}
return dp[N][W];
};