322. 給定不同面額的硬幣 coins 和乙個總金額 amount。編寫乙個函式來計算可以湊成總金額所需的最少的硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回 -1。
面試題08.11. 給定數量不限的硬幣,幣值為25分、10分、5分和1分,編寫**計算n分有幾種表示法。(結果可能會很大,你需要將結果模上1000000007)思路:(以leetcode 322為例)
1)揹包問題,看完題目就感覺像完全揹包問題(如果每種硬幣數量有限,那就是多重揹包)。
2)然後想到可以貪心,每次優先取最大面額的硬幣,但是單純的貪心不能保證是最優解,需要一些其他操作(如回溯)。
3)考慮動態規劃:
這個思路等價於完全揹包:
給定不同面額的硬幣coins,每個硬幣可以取任意次(無數次),求總金額為amount的最少硬幣個數,如果湊不成則返回-1。解法一:動態規劃
class solution(object):
def coinchange(self, coins, amount):
""":type coins: list[int]
:type amount: int
:rtype: int
"""dp = [float('inf') for _ in range(amount+1)]
dp[0] = 0
for i in range(1, amount+1):
for coin in coins:
if i >= coin:
dp[i] = min(dp[i], dp[i - coin] + 1)
return dp[-1] if dp[-1] != float('inf') else -1
解法二:完全揹包
class solution(object):
def coinchange(self, coins, amount):
""":type coins: list[int]
:type amount: int
:rtype: int
"""dp = [float('inf') for _ in range(amount+1)]
dp[0] = 0
for coin in coins: # 完全揹包,思路與dp相同,只是調換了內外迴圈
for i in range(coin, amount + 1): # 把if i >= coin並進來,省略if語句
dp[i] = min(dp[i], dp[i-coin] + 1)
return dp[-1] if dp[-1] != float('inf') else -1
解法三:貪心+dfs剪枝
待新增。
參考:solution/yong-bei-bao-wen-ti-si-xiang-lai-li-jie-ying-bi-zh/
leetcode 322 動態規劃
給定不同面額的硬幣 coins 和乙個總金額 amount。編寫乙個函式來計算可以湊成總金額所需的最少的硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回 1。輸入 coins 1,2,5 amount 11 輸出 3 解釋 11 5 5 1輸入 coins 2 amount 3 輸出 1說明 你...
leetcode322 零錢兌換
給定不同面額的硬幣 coins 和乙個總金額 amount。編寫乙個函式來計算可以湊成總金額所需的最少的硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回 1。示例 1 輸入 coins 1,2,5 amount 11輸出 3解釋 11 5 5 1 示例 2 輸入 coins 2 amount 3...
leetcode 322 零錢兌換
給定不同面額的硬幣 coins 和乙個總金額 amount。編寫乙個函式來計算可以湊成總金額所需的最少的硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回 1。示例 1 輸入 coins 1,2,5 amount 11 輸出 3 解釋 11 5 5 1示例 2 輸入 coins 2 amount ...