问题描述:
有一个揹包容量为10 ,现在4件物品,物品的重量和价值如下,请问揹包装最大的价值是多少?
1.首先解答这种问题,用动态规划的话,首先还是老套路,四部曲(不明白的,可以看我往期动态规划的博客)
1.确定状态(两个核心:1最后一步 2化成子问题)
2转移方程
3开始和边界条件
4计算顺序
(1)首先第一个,确定状态
w:表示揹包容量
W[2,3,4,5] :表示每件物品的重量
v[3,4,5,8]:表示每件物品的价值
分析“最后一步”是: 现在有k(这里是4)件物品可以选,揹包能装最大的价值。f(k,w) 表示当揹包容量为w,有k件物品可以选,揹包能装最大的价值
化成子问题 : 假如先看最后编号为k(这里是4)的物品, 这个时候有两种情况
放不下: f(k,w) = f(k - 1 , w)
放得下 :又分两种情况:
拿到包里:f(k,w) = f(k - 1 , w-Wk) +v[k]
不拿: f(k,w) = f(k - 1 , w)
(2)转移方程
(3)开始和边界条件
用一个表格来分析,首先f(0,0),f(0,1)....f(0,8)自然是0,因为编号为0的物体不存在,所以为0。
接着f(0,0),f(1,0)....f(8,0)自然是0,因为揹包容量为0,所有物品放不进去,所以为0
(4)计算顺序
其实就是从f[0]开始计算而已,并把他们都记录下来
//揹包问题
backpack() {
var n = 10; //揹包容量
var w = [0, 2, 3, 4, 5]; //重量
var v = [0, 3, 4, 5, 8]; //价值
var f = []; //下面构建二维数组的,f[k][w]代表前k件物品所能接受的最大值
//初始化二维数组
for (var i = 0; i < 5; i++) {
f[i] = [];
for (var j = 0; j < n + 1; j++) {
f[i][j] = 0;
}
}
for (var i = 1; i < 5; i++) {
for (var j = 1; j < n + 1; j++) {
if (w[i] > j) {
f[i][j] = f[i - 1][j];
} else {
f[i][j] = Math.max(f[i - 1][j], f[i - 1][j - w[i]] + v[i]);
}
}
}
console.log("揹包问题结果", f[4][8]);
}