代码随想录训练营第四十四天完全背包518. 零钱兑换 II377. 组合总和 Ⅳ

完全背包

题目链接 题目页面 (kamacoder.com)

讲解链接 代码随想录 (programmercarl.com)

相较于一维背包,完全背包的主要特征是在确定好最大背包的容量之后每个物体都可以被无限次选取,这时,主要需要改变就是双层for函数的结构 ,首先根据问题是排列问题还是组合问题,若是组合问题,外层仍然选用物品循环、内层选用背包循环;若是排列问题,外层则需要选用背包循环,内层选择物品数。此外,在内层顺序上,将变为从前往后:

    for(int i=0;i<weight.size();i++){
        for(int j=weight[i];j<bagSize;j++){
            dp[j]=max(dp[j],dp[j-weight]+values[i]);
        }
    }

518. 零钱兑换 II

题目链接 518. 零钱兑换 II - 力扣(LeetCode)

讲解链接 代码随想录 (programmercarl.com)

 本题就是典型的完全背包问题,数组中的硬币面额可以无限制选取,同时要求的是求取可以满足加起来是全部金额的组合数,那么函数也就变成了:

        for(int i=0;i<coins.size();i++){
            for(int j=coins[i];j<=amount;j++){
                dp[j]+=dp[j-coins[i]];
            }
        }

377. 组合总和 Ⅳ

题目链接 377. 组合总和 Ⅳ - 力扣(LeetCode)

讲解链接 代码随想录 (programmercarl.com)

 本题同样是集合中的元素可以被无限制选取,但是根据答案中的组合种类来看,本题相同元素不同的排列顺序算作不同组合,故而变成了排列问题,排列问题需要外层循环为背包容量、内层为物品件,两层循环都是从0开始,且在循环中递归函数前需要添加判定条件:j>nums[i]:

        for(int j=0;j<=target;j++){
            for(int i=0;i<nums.size();i++){
                if(j>=nums[i]&&dp[j]<INT_MAX-dp[j-nums[i]]){
                    dp[j]+=dp[j-nums[i]];
                }
            }
        }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值