题目详见518.零钱兑换Ⅱ
难点
- 初始化dp数组,i表示总金额为i dp[i]表示有多少方法拼成i
- 物品和背包遍历顺序
- 递推公式确定
解决方案
- 背包问题,物品数量是无限的,可以反复取因此是完全背包
- 组成总金额的硬币组合数!代表不考虑硬币摆放顺序
- 完全背包排列是先遍历背包,再遍历物品,因为要考虑排列顺序的不同,组合还是先物品再背包
- 完全背包和01背包在遍历背包容量的时候仍是完全是顺序,01是逆序
Talk is cheap,show me the code
class Solution:
def change(self, amount: int, coins: List[int]) -> int:
# 01背包是物品只能取一次 完全背包是物品数量是无限的
# 01 遍历背包是逆序 完全背包是顺序 可以反复取
'''
如果求组合数就是外层for循环遍历物品,内层for遍历背包。
如果求排列数就是外层for遍历背包,内层for循环遍历物品。
'''
dp = [0] * (amount+1)
dp[0] = 1
for i in range(len(coins)):# 物品
for j in range(coins[i],amount+1):
#求装满背包有几种方法类似的题目,递推公式基本都是这样的
dp[j] += dp[j-coins[i]]
return dp[amount]