518 零钱兑换II
给定不同面额的硬币和一个总金额。写出函数来计算可以凑成总金额的硬币组合数。假设每一种面额的硬币有无限个。
示例 1:
输入: amount = 5, coins = [1, 2, 5]
输出: 4
解释: 有四种方式可以凑成总金额:
5=5
5=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
解法
- 递归,超时
class Solution:
def change(self, amount: int, coins: List[int]) -> int:
def test(amount,coins,res):
num = 0
if res>amount:
return 0
if res==amount:
return 1
for i in range(len(coins)):
res += coins[i]
num += test(amount,coins[i:],res)
res -= coins[i]
return num
coins.sort()
return test(amount,coins,0)
- 动态规划
状态方程:
dp[i][j]表示前i个coins组合成钱j的组合数。
若 j<coins[i]:
dp[i][j] = dp[i-1][j]
否则: dp[i][j] = dp[i-1][j]+dp[i-1][j-coins[i]]
class Solution:
def change(self, amount: int, coins: List[int]) -> int:
dp = [0 for _ in range(amount+1)]
dp[0] = 1
for coin in coins:
for i in range(coin,amount+1):
dp[i] += dp[i-coin]
return dp[amount]