上一節總結了 0-1揹包,接著總結 完全揹包。在做題中總結套路,事半功倍!
引入322,零錢兌換,medium
518,零錢兌換ⅱ,medium
377,組合總和ⅳ,medium
139,單詞拆分,medium
完全揹包問題總結 引入
完全揹包的變體問題:物品可以無限次選取,且考慮物品放入的順序。
下面在具體題目中進行總結。
322,零錢兌換,medium
給定不同面額的硬幣 coins 和乙個總金額 amount。編寫乙個函式來計算可以湊成總金額所需的最少的硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回 -1。
你可以認為每種硬幣的數量是無限的。
示例 1:
輸入:coins = [1, 2, 5], amount = 11
輸出:3
解釋:11 = 5 + 5 + 1
示例 2:
輸入:coins = [2], amount = 3
輸出:-1
示例 3:
輸入:coins = [1], amount = 0
輸出:0
示例 4:
輸入:coins = [1], amount = 1
輸出:1
示例 5:
輸入:coins = [1], amount = 2
輸出:2
1 <=coins.length
<= 12
1 <=coins[i]
<= 231 - 1
0 <=amount
<= 104
解法一:二維(先遍歷物品,再遍歷揹包)
**:
class
solution
for(
int i =
1; i < n +
1; i++)}
return dp[n]
[amount]
> amount ?-1
: dp[n]
[amount];}
}
狀態壓縮:
class
solution
}return dp[amount]
> amount ?-1
: dp[amount];}
}
解法二:一維(先遍歷揹包,再遍歷物品)
518,零錢兌換ⅱ,medium
給定不同面額的硬幣和乙個總金額。寫出函式來計算可以湊成總金額的硬幣組合數。假設每一種面額的硬幣有無限個。
示例 1:
輸入: amount = 5, coins = [1, 2, 5]
輸出: 4
解釋: 有四種方式可以湊成總金額:
5=55=2+2+1
5=2+1+1+1
5=1+1+1+1+1
示例 2:
輸入: amount = 3, coins = [2]
輸出: 0
解釋: 只用面額2的硬幣不能湊成總金額3。
示例 3:
輸入: amount = 10, coins = [10]
輸出: 1
注意:
你可以假設:
0 <= amount (總金額) <= 5000
1 <= coin (硬幣面額) <= 5000
硬幣種類不超過 500 種
結果符合 32 位符號整數
要得到總的組合數,狀態轉移方程為:
d p[
i][j
]=dp
[i−1
][j]
+dp[
i][j
−coi
n]
dp[i][j] = dp[i - 1][j] + dp[i][j-coin]
dp[i][
j]=d
p[i−
1][j
]+dp
[i][
j−co
in]
**:
class
solution
}return dp[n]
[amount];}
}
狀態壓縮:通過觀察可以發現,dp
陣列的轉移只和dp[i][..]
和dp[i-1][..]
有關,所以可以壓縮狀態,進一步降低演算法的空間複雜度。
class
solution
}return dp[amount];}
}
下面兩題為完全揹包的變體:物品可以無限次選取,且考慮物品放入揹包的順序。
377,組合總和ⅳ,medium
給定乙個由正整數組成且不存在重複數字的陣列,找出和為給定目標正整數的組合的個數。
示例:
nums = [1, 2, 3]
target = 4
所有可能的組合為:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)
請注意,順序不同的序列被視作不同的組合。
因此輸出為 7。
139,單詞拆分,medium
給定乙個非空字串 s 和乙個包含非空單詞的列表 worddict,判定 s 是否可以被空格拆分為乙個或多個在字典**現的單詞。
說明:拆分時可以重複使用字典中的單詞。
你可以假設字典中沒有重複的單詞。
示例 1:
輸入: s = "leetcode", worddict = ["leet", "code"]
輸出: true
解釋: 返回 true 因為 "leetcode" 可以被拆分成 "leet code"。
示例 2:
輸出: true
注意你可以重複使用字典中的單詞。
示例 3:
輸入: s = "catsandog", worddict = ["cats", "dog", "sand", "and", "cat"]
輸出: false
完全揹包問題總結
做題步驟:
理解題意,判定此題為 完全揹包問題 或 完全揹包問題的變體。根據所求分為組合問題,true/false問題,最大最小問題。通常用一維 dpdp
dp陣列解題。
此題是否有特殊情況
動態規劃正常做法
1. 子問題:確定揹包和物品指代什麼,$dp[i]$ 返回值是什麼
2. base case:通常為 $dp[0]$
3. 狀態轉移方程:
**先遍歷揹包,再遍歷物品。**這樣才能保證放入順序。
組合問題公式 dp[i] += dp[i - num]
true/false問題公式 dp[i] = dp[i] or dp[i - num]
最大最小問題公式 dp[i] = min(dp[i], dp[i - num]+1) 或 dp[i] = max(dp[i], dp[i - num]+1)
最終返回結果
leetcode演算法刷題 五 動態規劃 三
今天的題目不是leetcode上面的。只是覺得動態規劃還是不算很熟練,就接著找了點dp的題練練 題目的意思 傳入乙個陣列,要求出它的最長遞增子串行的長度。例如 如在序列1,1,2,3,4,5,6,7中,最長遞增序列為1,2,4,6,所以長度為4。分析 這道題我們可以用動態規劃來做。對於陣列的前i個元...
leetcode刷題 動態規劃
動態規劃 英語 dynamic programming,簡稱 dp 是一種在數學 管理科學 電腦科學 經濟學和生物資訊學中使用的,通過把原問題分解為相對簡單的子問題的方式求解複雜問題的方法。動態規劃常常適用於有重疊子問題和最優子結構性質的問題,動態規劃方法所耗時間往往遠少於樸素解法。動態規劃背後的基...
Leetcode刷題 190713 動態規劃
輸入乙個陣列,陣列中每個元素代表乙個房子,我們作為robber可以對每個房子進行rob。但是規定不能同時又兩個相鄰的房子被robbed。陣列中每個元素的值代表房子的價值,需要我們輸出經過rob後最大的收益是多少。很明顯考察的是動態規劃,每檢查乙個房子都有兩種狀態即rob和no rob。對應的價值方程...