LeetCode: 08.11 硬币 & 518. 零钱兑换||

完全背包问题,即资源没有数量限制

题目

硬币。给定数量不限的硬币,币值为25分、10分、5分和1分,编写代码计算n分有几种表示法。(结果可能会很大,你需要将结果模上1000000007)

解法

根据背包九讲里面的完全背包的递推公式,可以简化时间复杂度。本来完全背包问题可以拆分为01背包,但是就多出一个for循环。
dp[i][j]描述了只用前i个硬币, 能拼出钱j的方案数目。初始化的话,如果只用一分硬币,那所有钱数只有一种方案。注意。第二维是n+1的长度,且第一位初始化为1,因为如果j - coin==0, 那么用coin只有一种方案能拼出j,就是全部都用coin
dp的定义非常重要。

class Solution:
    def waysToChange(self, n: int) -> int:
        coins = [1, 5, 10, 25]
        dp = [[0] * (1+n) for _ in range(4)] # 4, n
        for i in range(n+1): # 初始化 只用1分硬币 只有1种
            dp[0][i] = 1
        for i in range(4):
            dp[i][0] = 1
        for i in range(1, 4):
            coin = coins[i]
            for j in range(n+1):
                if j - coin >= 0:
                	# 注意这里是对完全背包的优化 当前状态i下的j-coin
                    dp[i][j] = dp[i][j - coin] + dp[i-1][j]
                else:
                    dp[i][j] = dp[i-1][j]
                dp[i][j] = dp[i][j] % 1000000007
        return dp[3][-1]

另外组合总数IV 和这道题相似,但解法完全不一样。组合总数IV要求,只要顺序不相同,哪怕值是一样的,都算不一样的组合。这和背包问题的解法是完全不一样的。完全背包问题的组合是独一无二的,即第k个元素,要吗加0次,要吗加1次。要吗加2次。。。,直到超出容量。 不关心加的位置在哪。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值