思路分析:
每次遍历到的第i个物品,根据 w[i] 和 v[j] 来确定是否需要将该物品放入背包中。即对于给定的 n 个物品,设 v[i]、w[i] 分别为第 i 个物品的价值和重量,C为背包的容量。再令 v[i][j] 表示在前 i 个物品中能够装入容量为 j 的背包中的最大价值。则有:
- v[i][0] = v[0][j] = 0;
- 当 w[i]>j 时:v[i][j] = v[i-1][j]
- 当 j>=w[i] 时:v[i][j] = max{v[i-1][j],v[i]+v[i-1][j-w[i]]}
问:4磅的背包容量,可以装入以下哪些东西,使得容量最大,最大为多少。
物品 | 重量(w[i]) | 价格(v[i]) |
---|---|---|
吉他(G) | 1 | 1500 |
音响(S) | 4 | 3000 |
电脑(L) | 3 | 2000 |
手动使用动态规划,得出的结果为:
物品 | 0磅 | 1磅 | 2磅 | 3磅 | 4磅 |
---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | |
吉他(G) | 0 | 1500(G) | 1500(G) | 1500(G) | 1500(G) |
音响(S) | 0 | 1500(G) | 1500(G) | 1500(G) | 3000(S) |
电脑(L) | 0 | 1500(G) | 1500(G) | 1500(G) | 2000(L)+1500(G) |
以下代码参考 js动态规划—背包问题 这篇文章:
//动态规划背包问题
// c[i][j] 表示 前 i个物品,装入容量为 j的最大价值
// v[i] 表示第 i件物品的价值
// w[i] 表示每件物品的重量
//W 表示背包的容量
// use[i] , 为 0 表示没取第 i件物品,为1表示取了第i件物品
function main(v,w,W){
var n = v.length;
var c = [];
var use = [];
for(var i = 0; i <= n ; i++){
c[i] = [];
use[i] = 0;
for(var j = 0; j <= W ; j++){
if(i == 0 || j == 0){
c[i][j] = 0;
}
}
}
v.unshift(0); //第0件物品,价值为0
w.unshift(0); //第0件物品,重量为0
for(var i = 1; i <= n; i++){
for(var j = 1; j <= W; j++ ){
if(j < w[i]){
c[i][j] = c[i-1][j];
}else{
c[i][j] = Math.max(c[i-1][j],c[i-1][j-w[i]]+v[i]);
}
}
}
//逆向获取加入的物品
var j = W;
for(var i = n; i > 0; i--){
if(c[i][j] > c[i-1][j]){
use[i] = 1;
j=j-w[i];
}
}
console.log(use);
return c[n][W];
}
console.log(main([6,3,5,4,6],[2,5,4,2,3],10))
本文为算法笔记,需要详细视频学习请点击以下链接