01揹包是動態規劃中比較簡單的一個問題,其中的關鍵在於找到狀態轉換方程。java
假設編號分別爲a,b,c,d,e的五件物品,重量分別是2,2,6,5,4,價值分別是6,3,5,4,6,如今有一個承重爲10的揹包,如何裝入物品具備最大價值?數組
首先假設有一個國王且手下有大臣A和大臣B,聰明的國王將這個問題分爲放入物品a和不放入物品a兩種狀況。而後國王告訴大臣A假如已經放了物品a, 那麼剩下b,c,d,e四件商品放入大小爲8的揹包中的最大價值(其中8來自於總重量10減去物品a的重量2),而後再告訴大臣B假如沒有放入物品a, 那麼在b,c,d,e四件商品中放入大小爲10的揹包中的最大價值。spa
而國王只須要比較兩個大臣的答案就能夠獲得最終答案。大臣A採用一樣方法把任務分給手下有A1和A2兩我的,大臣B同理。依次下去,便可獲得最終的答案。.net
以上能夠看出,關鍵步驟是將問題分解爲放入物品a與不放入物品a兩種狀況中的最大值,並推廣的全部的物品。這也是01的由來。code
用圖形表示出來就是下面這張表。blog
首先注意的是該表是從左下開始填的,左邊紫色列標示物品編號,並對應的有重量與價值,第一行標示揹包重量。(b, 5)表示b、c、d、e四個物品放入大小爲5的揹包中的最大值。(a, 10)就是abcde五種商品放入容量爲10的揹包中的最大價值,這正好就是題目的答案。圖片
如今咱們開始學怎麼填這張表,先隨便挑一個表格(a,9),此時揹包容量爲9,能夠選abcde五種物品,咱們要找出容量的最大值,根據上述思路分爲放入物品a和不放入物品a兩種狀況。ip
狀況a: 假如放入物品a, 則揹包容量變爲9-2=7,還剩b,c,d,e四種物品。因此該狀況下的最大值 = (b,7) + 物品a的價值6,即9+6get
狀況b: 假如不放入物品a, 揹包容量不變爲9,還剩b,c,d,e四種物品。因此該狀況下的最大值 = (b, 9),即10it
因此如今(a, 9) = max( (b,7)+6, b(9) ) = max(9+6,10) = 15。
一樣的步驟填滿其餘的表格便可。
下面是方法2的js實現
function packageMaxValue(weight, value, size){ // 省略參數合法性校驗 let bagMatrix = [] for(let w = 0; w <= size; w++) { // js不能直接建立二維數組,因此在此初始化數組 bagMatrix[w] = [] for (let j = 0; j < 5; j++) { // 揹包的容量爲0,那麼一個東西也裝不下,此時的值確定也是爲0 if(w === 0) { bagMatrix[w][j] = 0 continue } // 揹包的容量小於物品j的重量,那麼就沒有上述狀況a了 if(w < weight[j]){ bagMatrix[w][j] = bagMatrix[w][j-1] || 0 continue } bagMatrix[w][j] = Math.max((bagMatrix[w-weight[j]][j-1] || 0) + value[j], bagMatrix[w][j-1] || 0) } } return bagMatrix } let weight = [4, 5, 6, 2, 2] let value = [6, 4, 5, 3, 6] console.log(packageMaxValue(weight, value, 10))