1. 程式人生 > >【LeetCode & 劍指offer刷題】動態規劃與貪婪法題16:揹包問題總結

【LeetCode & 劍指offer刷題】動態規劃與貪婪法題16:揹包問題總結

【LeetCode & 劍指offer 刷題筆記】目錄(持續更新中...)

揹包問題總結

揹包問題   揹包問題 (Knapsack problem x ) 有很多種版本,常見的是以下三種:
  • 0-1 揹包問題 (0-1 knapsack problem):每種物品只有一個
  • 完全揹包問題 (UKP, unbounded knapsack problem):每種物品都有無限個可用
  • 多重揹包問題
    (BKP, bounded knapsack problem):第 i 種物品有 n[i] 個可用
  0-1 揹包問題 0-1揹包中一種物體只有一個,放入數量為0或者1 定義狀態 dp[i][j],表示“ 把前 i 種物品裝進重量限制為 j 的揹包可以獲得的最大價值 v[i]表示物品i的價值,w[i]表示物品i的重量,j為揹包的重量限制 0/1揹包問題狀態轉移方程便是:    dp[i][j] = max{dp[i − 1][j], 
dp[i − 1] [j − w[i]] + v[i]}     兩項分別代表物品i不選擇或者選擇的情況 (減去的代表選擇的) 時間複雜度是O(nb),空間也是O(nb),假設有n種物品,重量限制為b     可以簡化為:    d[j]=max{d[j],d[j-w[i]]+v[i]}; 注意:遍歷j時務必從右到左,因為d[j]只依賴於上一階段的結果,從右到左避免覆蓋上階段有用結果
    完全揹包問題 完全揹包中一種物體可以有多個,可以放滿揹包為止 完全揹包問題狀態轉移方程是:    dp[i][j] = max{dp[i − 1][j],  dp[i] [j − w[i]] + v[i]} 兩項分別代表物品i不選擇或者選擇,由於對物品i沒有限制,故後一項為dp[i]而非上面的dp[i-1]   或用以下遞推式(上面的效率要高一點): dp[i][j] = max( dp[i-1][j-k*w[i]] + k*v[i] ),   k為選擇物品的個數, k=0,1,2...j/w[i] (0 ≤ k ∗ w[i] ≤ j) 基於前i-1個物品,在選擇不同個數的物品i的方案中選擇最大的那個 (和問題 coin change 比較相似)   可以簡化為:    d[j] = max{d[j], d[j-k*w[i]] + k*v[i]} 注意:遍歷j時務必從右到左,原因同上   多重揹包問題 多重揹包中一種物體可以有多個,個數有人為限定(也不能超過揹包容量) 多重揹包問題狀態轉移方程是: dp[i][j] = max( dp[i−1][j−k∗w[i]] + k∗v[i] )    0 ≤ k ≤ n[i],0 ≤ k ∗ w[i] ≤ j n[i]為物品i限制的個數 基於前i-1個物品,在選擇不同個數的物品i的方案中選擇最大的那個   可以簡化為:    d[j] = max{d[j], d[j-k*w[i]] + k*v[i]} 注意:遍歷j時務必從右到左,原因同上   參考: 【動態規劃】揹包問題(一) 01揹包 完全揹包 多重揹包 - A.S.KirigiriKyouko - 部落格園 揹包問題總結