leetcode-零钱兑换[518]
题目描述
给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。
请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。
动态规划
本题与爬楼梯很相似,可以从最后一个组成面额的最后一个硬币考虑。例如组成面额5(dp[5])的最后一个硬币共有三种情况:
- 最后一枚硬币为1,dp[5-1]
- 最后一枚硬币为2,dp[5-2]
- 最后一枚硬币为5,dp[5-3]
\(dp[5] = dp[5-1]+dp[5-2]+dp[5-5]\)
- 状态定义:dp[n]表示组成面额n的所有组合数
- 状态转移方程:\(dp[n] = \left\{dp[n-coin]|n\in coins \right\}\)
\(dp[0]=0\)
代码实现
class Solution:
def change_pailie(self, amount: int, coins: List[int]) -> int:
dp = [0]*(amount+1)
dp[0] = 1
#枚举金额
for i in range(1,amount+1):
#枚举面额
for coin in coins:
if i<coin:
continue
dp[i] +=dp[i-coin]
# 如何去重
return dp[amount]
def change_zuhe(self, amount: int, coins: List[int]) -> int:
dp = [0]*(amount+1)
dp[0] = 1
#枚举面额
for coin in coins:
#枚举金额
for i in range(1,amount+1):
if i<coin:
continue
dp[i] +=dp[i-coin]
return dp[amount]