D - Knapsack 1
❀ 題目傳送門 ❀
❀ 解題小技巧 ❀
就是背包問題。
…
…好像有點不負責任w \
核心觀念
首先要先有兩個陣列分別儲存「物品價值」跟「物品重量」(下面分別為 v 跟 w)
再來就是 dp 陣列,其中 dp[i]
的意思為背包限重為i
時,所能拿的最大價值。
接著要用for
迴圈跑過每一個物品,並決定要不要拿(最外圈是選定一個物品,第二圈是決定在當前重量要不要拿)。 \
轉移式
讓我們來看看轉移式: dp[j] = max(dp[j], dp[j-w[i]] + v[i]);
對,他比較難懂一點,讓我們慢慢來。
如果拿了東西,那價值就會增加v[i]
,但同時重量也得花掉w[i]
。
換句話說,若拿了東西,問題可以改想為:限重為當前重量-w[i]
,的最佳策略。
因而得出dp[j-w[i]] + v[i]
轉移式疑問
那為什麼要跟dp[j]
比誰大?
當拿到第i
個物品的時候,就要對dp[限重] ~ dp[w[i]]
檢查數值是否更新
也就是,拿了東西會不會比不拿還大,若比較大則更新,較小則不更新。
「海星海星,你腦袋還好吧,不拿怎麼會比拿還大」
是因為第i
圈的dp[j]
意思是,我們拿了i
個物品後,背包限重為j
時,所能拿的最大值。
舉個淺例:
1 | 原題目: |
所以我們會比較的是已經挑過i - 1
物品最划算的背包,跟現在拿了比較誰價值更高
而不是空空如也的背包,跟現在拿了比較誰價值更高 \
補充
這邊有個細節:dp[限重] ~ dp[w[i]]
而不是dp[w[i]] ~ dp[限重]
至於為什麼,等到出現無限背包問題再說吧!
❀ 參考程式碼 ❀
1 |
|
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 MysteryStarfish's blog!
評論
Facebook Comments Twikoo