背包问题:
给定 n 种物品和一个容量为 C 的背包,物品 i 的重量是 w[i],其价值为 v[i] 。
问:应该如何选择装入背包的物品,使得装入背包中的物品的总价值最大?
分析:
n种物品,每一种要么放入背包,要么不放(在背包装不下的情况不放)
解决:
使用一个数组temp来存储当面对第i件商品,背包容积为j时的最大价值,我们很容易分析出temp的计算规则:
1)、当第i件商品的重量w[i]大于j的时候,因为这个时候第i件商品放不进背包,所以temp[i][j]等于temp[i-1][j];
2)、如果w[i]小于j的时候,我们就要考虑第i件商品是不是该放入背包。如果放入,则temp[i][j]等于temp[i-1][j-w[i]]+v[i],如果不放,则temp[i][j]等于temp[i-1][j],为了价值最大,肯定我们取放或者不放两种情况的最大值,由此可以发现temp数组有一个递归的规律。因此可以编码实现temp数组:
(function MaxPackage () {
// 为了递归初始化temp,所以让v和w的第0位为0
let v = [0, 10, 8, 2, 6, 3, 7, 2]
let w = [0, 2, 4, 6, 2, 2, 5, 1]
let temp = []
let n = 7
let c = 12
// temp先全部初始化
for (let l = 0; l <= n; l++) {
temp[l] = []
for (let m = 0; m <= c; m++) {
temp[l][m] = 0
}
}
// 再执行找给定质量最大背包价值
for (let i = 1; i <= n; i++) {
for (let j = 1; j <= c; j++) {
if (j >= w[i]) {
temp[i][j] = findMax(temp[i - 1][j], temp[i - 1][j - w[i]] + v[i])
} else {
temp[i][j] = temp[i - 1][j]
}
}
}
console.log(temp)
// 当背包最大容量为c的时候找最大价值时对应要放哪些物品
let x = [0, 0, 0, 0, 0, 0, 0]
for (let h = n; h > 0; h--) {
// 因为如果temp[h][c] === temp[h - 1][c]说明第h件物品不会放进去,反正会放进去
if (temp[h][c] === temp[h - 1][c]) {
x[h] = 0
} else {
x[h] = 1
c = c - w[h]
}
}
console.log(x)
})()
// 找最大值的函数
function findMax (a, b) {
if (a > b) {
return a
} else {
return b
}
}