//每種物品僅有一件,可以選擇放或不放
//即f[i][w]表示前i件物品恰放入一個容量為w的背包可以獲得的最大價值。
//則其狀態轉移方程便是:f[i][w]=max{f[i-1][w],f[i-1][w-weights[i]]+values[i]} (這是最根本的算法)
//其實背包問題有好多版本:
/*
* 01背包(ZeroOnePack): 有N件物品和一個容量為V的背包。每種物品均只有一件,第i件物品的費用是c[i],價值是w[i]。求解將哪些物品裝入背包可使價值總和最大。
完全背包(CompletePack): 有N種物品和一個容量為V的背包,每種物品都有無限件可用。第i種物品的費用是c[i],價值是w[i]。求解將哪些物品裝入背包可使這些物品的費用總和不超過背包容量,且價值總和最大。
多重背包(MultiplePack): 有N種物品和一個容量為V的背包。第i種物品最多有n[i]件可用,每件費用是c[i],價值是w[i]。求解將哪些物品裝入背包可使這些物品的費用總和不超過背包容量,且價值總和最大。
* */
//動態規划背包問題
// 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))