题目:
给定不同面额的硬币和一个总金额。写出函数来计算可以凑成总金额的硬币组合数。假设每一种面额的硬币有无限个。
思路:
dp[i][j]:用前i个硬币凑成金额j的组合数
解答:
方法一:
class Solution:
def change(self, amount: int, coins: List[int]) -> int:
n=len(coins)
#dp[i][j]:用前i个硬币凑成金额j的组合数d,dp[0][x]:表示一个硬币都不用
dp=[[0]*(amount+1) for i in range(n+1)]
dp[0][0]=1
for i in range(n):
c=coins[i]
for j in range(amount+1):
if c>j:
dp[i+1][j]=dp[i][j]
else:
#要么不用第i个硬币,要么用第i个硬币
dp[i+1][j]=dp[i][j]+dp[i+1][j-c]
return dp[n][amount]
优化:
class Solution:
def change(self, amount: int, coins: List[int]) -> int:
n=len(coins)
#dp[i][j]:用前i个硬币凑成金额j的组合数d,dp[0][x]:表示一个硬币都不用
dp=[[0]*(amount+1) for i in range(n+1)]
dp[0][0]=1
for i in range(n):
c=coins[i]
for j in range(amount+1):
#r若不用第i个硬币
dp[i+1][j]=dp[i][j]
if c<=j:
#若用第i个硬币
dp[i+1][j]+=dp[i+1][j-c]
return dp[n][amount]
法二:
class Solution:
def change(self, amount: int, coins: List[int]) -> int:
#dp[i][j]:用前i个硬币凑成金额j的组合数
dp=[0]*(amount+1)
dp[0]=1
for c in coins:
for j in range(c,amount+1):
#要么不用第i个硬币,要么用第i个硬币
dp[j]+=dp[j-c]
return dp[amount]