食物 | 質量/weight (100g) | 價值/value(10g) |
---|---|---|
米飯 | 2 | 4 |
黃瓜 | 1 | 5 |
西紅柿 | 1 | 8 |
牛肉 | 3 | 10 |
動動吃貨的小腦筋,就知道,養分價值最大化的選擇是 牛肉+黃瓜+西紅柿 共 23(10g)養分! 但是該怎麼使用程序計算出答案呢? html
肚子的資源有限,對每一種食物有兩種選擇:吃或者不吃。 判斷的依據有兩點:數組
(1)肚子可否裝得下食物?bash
(2)吃他的價值,是否比不吃他的價值大?大則吃下,不大則不吃。spa
假設d(i,w)表示肚子剩w(g)時,有 i 樣食物可供選擇,咱們能獲得的最大價值。i 表示第 i 樣食物。咱們須要求的是d(4,5).net
根據上面的邏輯(1)設計
若是肚子裝不下,由於食物i沒裝進去,那麼d(i,w) = d(i-1,w)code
肚子裝得下,那我須要判斷 [不放] d(i-1,w) 和 [放] d(i-1,w-w[i])+v[i] 誰大。cdn
結合上面兩條規律,咱們獲得:htm
d(i, w)=max{ d(i-1, w), d(i-1,w-w[i]) + v[i] }blog
咱們給每樣食物加上序號
假如咱們考慮吃或不吃從下向上按照序號順序 4,3,2,1
d(4,5)表示只有牛肉、西紅柿、黃瓜、米飯能夠選擇時,能獲得的最大價值。若是我知道d(3,5)和d(3,2),我就能獲得d(4,5)
d(4 , 5)=max{ d(3,5) , d(3,5-3) }=max{ d(3,5) , d(3,2) + 10}
d(4,5)表示只有西紅柿、黃瓜、米飯能夠選擇時,能獲得的最大價值。若是我知道d(2,5)和d(2,4),我就能獲得d(3,5)
d(3 , 5)=max{d(2,5) , d(2,4)}
按照上面的往下分解,最終都會指向d(0,w)~邏輯以下圖:
d(0,w)表明選 0 件物品的放入揹包容量爲 w 的揹包的最大價值,因此爲 0。d(i,0)表明選 i 件物品放入揹包容量爲 0 的揹包的最大價值,也爲 0。
將樹圖的d值繼續整理獲得最優價值表
var value = [5, 8, 4, 10],
size = [1, 1, 2, 3],
d = [],
n = 4,
C = 5;
//初始化數組
for (var k = 0; k <= n; ++k) {
d[k] = [];
}
for (var i = 0; i <= n; ++i) {
for (var w = 0; w <= C; ++w) {
d[i][w] = (i == 0) ? 0 : d[i - 1][w];
if (i > 0 && w >= size[i - 1])
d[i][w] = Math.max(d[i - 1][w], d[i - 1][w - size[i - 1]] + value[i - 1]);
}
}
console.log(d[4][5])//23
複製代碼
01揹包問題的這種解法讓我感覺到了遞歸的強大,將大問題轉換成小問題,而後獲得小問題的答案向上求解!
連接:www.nowcoder.com/questionTer… 來源:牛客網 一種雙核CPU的兩個核可以同時的處理任務,如今有n個已知數據量的任務須要交給CPU處理,假設已知CPU的每一個核1秒能夠處理1kb,每一個核同時只能處理一項任務。n個任務能夠按照任意順序放入CPU進行處理,如今須要設計一個方案讓CPU處理完這批任務所需的時間最少,求這個最小的時間。
動態規劃之01揹包問題--表格思路來源