【leetcode题解——动态规划之完全背包】518.零钱兑换II(python版本详解+表格+dp五部曲)

博客内容介绍了如何使用动态规划解决零钱兑换问题,强调了组合数而非排列数的概念。通过五步解析动态规划的思路,包括初始化、状态转移方程、遍历顺序等,并给出了一段Python代码实现。示例展示了如何计算给定金额和硬币面额下的组合数。
摘要由CSDN通过智能技术生成

518. 零钱兑换 II

重点:

本题求组合数,而非排列数。

例如示例:

5 = 2 + 2 + 1

5 = 2 + 1 + 2

这是一种组合,都是 2 2 1,而(2,2,1)(2,1,2)为两种排列

组合不强调元素之间的顺序,而排列强调。

dp五部曲:

1. dp[j]:满足总金额为j的硬币组合数

2. 公式:dp[j]+=dp[j-coins[i]]

dp[j] (考虑coins[i]的组合总和) 就是所有的dp[j - coins[i]](不考虑coins[i])相加。

3. 初始化:dp[0]初始化为1,其余初始化为0

从dp[i]的含义上来讲就是,凑成总金额0的货币组合数为1。

下标非0的dp[j]初始化为0,这样累计加dp[j - coins[i]]的时候才不会影响真正的dp[j]

4. 遍历顺序:外层i表示不同面额的硬币,内层j表示总金额,都是正序

外层for循环遍历物品,内层for循环遍历背包容量:求得组合数

假设:coins[0] = 1,coins[1] = 5。

那么就是先把1加入计算,然后再把5加入计算,得到的方法数量只有{1, 5}这种情况。而不会出现{5, 1}的情况。

外层for循环遍历背包容量,内层for循环遍历物品:求得排列数

背包容量的每一个值,都是经过 1 和 5 的计算,包含了{1, 5} 和 {5, 1}两种情况。

5. 举例推导

amount = 5, coins = [1, 2, 5]

j=0j=1j=2j=3j=4j=5
i=0111111
i=1112233
i=2112234
得到dp[5]=4

代码:

class Solution:
    def change(self, amount: int, coins: List[int]) -> int:
        lenc=len(coins)
        dp=[0]*(amount+1)
        dp[0]=1
        for i in range(lenc):
            for j in range(coins[i],amount+1):
                dp[j]+=dp[j-coins[i]]
        return dp[amount]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

别熬夜了您

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值