給定一組物品,每種物品都有本身的重量和價格,在限定的總重量內,咱們如何選擇,才能使得物品的總價格最高。javascript
const tList = [1, 2, 3, 4, 5] // 物品體積 const vList = [3, 4, 10, 7, 4] // 物品價值 const map = {} function getbag (i, v) { if (i === 0) { if (tList[0] > v) { return 0 } else { return vList[0] } } if (v >= tList[i]) { // 放與不放 取最大值 return Math.max(getbag(i - 1, v), vList[i] + getbag(i - 1, v - tList[i])) } else { return getbag(i - 1, v) } } console.log(getbag(5, 3))
f[i][j] = max(f[i-1][j], f[i-1][j-w[i] + v[i])
變成f[i][j] = max(f[i-1][j], f[i-1][j-k*w[i]]+k*v[i])
且0<k<j/w[i]const bag = 61 const goodList = [{ name: 'apple', w: 2, v: 2 }, { name: 'book', w: 3, v: 7 }, { name: 'iphone', w: 5, v: 40 }, { name: 'mac', w: 20, v: 70 }] const goodLen = goodList.length const wList = goodList.map(item => { return item.w }) const vList = goodList.map(item => { return item.v }) const nList = goodList.map(item => { return item.name }) const map = {} function getMax(i, j) { let count = Math.floor(j/wList[i]) if (i === 0) { map[i] = map[i] || {} map[i][j] = count return count * vList[i] } if (count === 0) { map[i] = map[i] || {} map[i][j] = 0 return getMax(i-1, j) } else { let maxIdx = 0 let maxVal = 0 for (let k = 1; k < count + 1; k++) { let kr = getMax(i - 1, j - wList[i] * k) + vList[i] * k if (kr > maxVal) { maxVal = kr maxIdx = k } } map[i] = map[i] || {} map[i][j] = maxIdx return maxVal } } const val = getMax(goodLen - 1, bag) let bagCost = 0 function getSelect(i, j) { if (i < 0) { return } let count = 0 if (map[i] && map[i][j]) { count = map[i][j] } bagCost += wList[i] * count console.log(`物品${nList[i]} x ${count}`) getSelect(i - 1, j - count * wList[i]) } getSelect(goodLen - 1, bag) console.log(`總價值${val}`) console.log(`揹包負載${bagCost}/${bag}`) // 物品mac x 1 // 物品iphone x 8 // 物品book x 0 // 物品apple x 0 // 總價值390 // 揹包負載60/61
const bag = 12 const goodList = [{ name: 'apple', w: 1, v: 2 }, { name: 'book', w: 2, v: 10 }, { name: 'iphone', w: 5, v: 40 }, { name: 'mac', w: 10, v: 100 }] const goodLen = goodList.length const wList = goodList.map(item => { return item.w }) const vList = goodList.map(item => { return item.v }) const nList = goodList.map(item => { return item.name }) const map = {} const path = {} function setMap(i, w, v) { map[i] = map[i] || {} map[i][w] = v } function setPath(i, w) { path[i] = path[i] || {} // 在重量爲w的包裏,是否放置第i個物品以達到最大價值 path[i][w] = true } function getMax(i, w) { if (i === 0) { if (wList[i] > w) { setMap(i, w, 0) return 0 } else { setMap(i, w, vList[i]) setPath(i, w) return vList[i] } } if (wList[i] > w) { let plan = getMax(i-1,w) setMap(i, w, plan) return plan } else { let planA = getMax(i-1, w) let planB = getMax(i-1, w-wList[i]) + vList[i] if (planB > planA) { setMap(i, w, planB) setPath(i, w) return planB } else { setMap(i, w, planA) return planA } } } const val = getMax(goodLen - 1, bag) let bagCost = 0 function getSelect(i, j) { if (i < 0) { return [] } let arr = [] if (path[i] && path[i][j]) { arr.push(i) bagCost += wList[i] console.log(`物品${nList[i]} x 1`) return arr.concat(getSelect(i-1, j-wList[i])) } else { console.log(`物品${nList[i]} x 0`) return arr.concat(getSelect(i-1, j)) } } getSelect(goodLen - 1, bag) console.log(`物品總價值${val}`) console.log(`揹包負重${bagCost}/${bag}`) // 物品mac x 1 // 物品iphone x 0 // 物品book x 1 // 物品apple x 0 // 物品總價值110 // 揹包負重12/12