leetcode-零钱兑换[518]

题目描述

给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。
请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。
image

动态规划

本题与爬楼梯很相似,可以从最后一个组成面额的最后一个硬币考虑。例如组成面额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]\)

  1. 状态定义:dp[n]表示组成面额n的所有组合数
  2. 状态转移方程:\(dp[n] = \left\{dp[n-coin]|n\in coins \right\}\)

\(dp[0]=0\)

image

代码实现

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]

posted @ 2022-03-08 22:30  topbookcc  阅读(30)  评论(0编辑  收藏  举报
/* 鼠标点击求赞文字特效 */