刷题第三十七天 完全背包概念 518.零钱兑换Ⅱ 377.组合总和Ⅳ

文章讨论了完全背包问题的两种遍历顺序(先物品后背包和先背包后物品),并介绍了如何用动态规划解决。`combinationSum4`和`change`函数展示了在不同顺序下计算装满背包种类的方法,一个是组合数,另一个涉及排列数。
摘要由CSDN通过智能技术生成

和0-1背包的差别在于物品可以重复使用无限多次,所以在遍历背包的时候需要正序遍历,重复使用前面的状态

完全背包问题的遍历顺序 先物品还是先背包都可以,因为不影响状态的更新

先物品再背包是组合数,物品的顺序是不变的

先背包再物品是排列数,物品的顺序会改变

class Solution:
    def change(self, amount: int, coins: List[int]) -> int:
        ## dp数组的含义,从i个物品中任取,装满amount的背包有多少种
        ## 本题的coin 价值和重量相同
        dp = [0] * (amount + 1)
        dp[0] = 1
        for i in range(len(coins)):
            for j in range(amount + 1):
                if j >= coins[i]:
                    dp[j] += dp[j - coins[i]]
        return dp[amount]

计算装满背包有多少种类的问题的递推公式就是

dp[j] += dp[j - weight[i]]

因为装满j的背包的种类由所有装满j-weight[i]背包的种类求和得到,因为所有装满j-weight[i]的背包都可以和i组成装满j的背包

class Solution:
    def combinationSum4(self, nums: List[int], target: int) -> int:
        dp = [1] + [0]* (target)
        for j in range(target + 1):
            for i in range(len(nums)):
                if j >= nums[i]:
                    dp[j] += dp[j - nums[i]]
        return dp[target]

因为存在顺序不同的序列,实际上求排列的数目,就是先遍历背包再遍历物品

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值