有 N 件物品和一个容量是 V的背包。每件物品只能使用一次。
第 i件物品的体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出最大价值。
每件物品只能选一次,对于每种物品,我们有两种选择
朴素版解法:二维空间解法
1.不选 -> f[i][j]=f[i-1][j]
等于选前i-1个物品,空间为j情况下的最优解
2.选 -> f[i][j]=f[i-1][j-values[i]]+weights[i]
如果选的话,前i-1个物品的体积最多为j-values[i]
滚动数组解法
1.不选 -> f[j]=f[j]
等于不改变数据
2.选 -> f[j]=f[j - weights[i]] + values[i])
如果选的话,前i-1个物品的体积最多为j-values[i]
例子:
//背包大小
let maxWeight = 10
//物品价值数组
let values = [6,3,5,4,6]
//物品重量数组
let weights = [2,2,6,5,4]
//创建一个背包
var f = [Int].init(repeating: 0, count: maxWeight + 1)
//遍历所以物品
for i in 0..<values.count {
//看背包剩余容量
for j in (1...maxWeight).reversed() {
//选择的物品重量不能超过背包剩余容量
if weights[i] <= j {
f[j] = max(f[j], (f[j - weights[i]] + values[i]))
}
}
}
//打印背包最大的值
print("打印背包最大的值:\(f[maxWeight])")
打印结果:
打印背包最大的值:15
参考:背包九讲和FlyElephant