吃貨如何理解01揹包問題

揹包問題

先從栗子出發,你是一個有理想的吃貨,你的肚子只能容納500g 的食物,爲了保證你獲得的價值(養分)最大化,有如下幾份食物能夠選擇

食物 質量/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揹包問題的這種解法讓我感覺到了遞歸的強大,將大問題轉換成小問題,而後獲得小問題的答案向上求解!

2. 例題

連接:www.nowcoder.com/questionTer… 來源:牛客網 一種雙核CPU的兩個核可以同時的處理任務,如今有n個已知數據量的任務須要交給CPU處理,假設已知CPU的每一個核1秒能夠處理1kb,每一個核同時只能處理一項任務。n個任務能夠按照任意順序放入CPU進行處理,如今須要設計一個方案讓CPU處理完這批任務所需的時間最少,求這個最小的時間。

3. 資料

動態規劃之揹包問題(一)

動態規劃之01揹包問題--表格思路來源

經過金礦模型介紹動態規劃

相關文章
相關標籤/搜索