LeetCode刷题整理——背包问题

这篇博客详细介绍了如何运用动态规划解决LeetCode中的完全背包问题,包括组合总和和零钱兑换等题目。作者指出,对于完全背包问题,关键在于理解状态转移方程,并避免在C++中出现整数溢出。通过调整循环顺序,可以解决组合问题中的重复计算,确保结果正确。同时,博客还展示了如何将动态规划应用于最小硬币组合问题。

大佬的动态规划题解
LeetCode 背包问题总结

完全背包(物品数量无限)

LeetCode 377 组合总和 4

只需要知道有多少种组合(其实是求排列,与顺序有关),不需要知道是哪些组合。最开始以为和LeetCode 39很像,用回溯剪枝搜索,超时(回溯的复杂度很大)。这题不用知道具体的组合可以不用回溯,属于背包问题中的完全背包问题。
然后这题用C++的话,最后一个用例会超过INT_MAX,所以比java等要加一个判断条件。

用maximum[i] 表示背包里放了重量和为i 的物品时的方案数。
初始状态:maximum[0] 什么都没放,只有一种情况。则maximum[0]=1。其他情况还没有计算,都初始化为零。
式子:在到达maximum[i]之前的一步状态,可能有多种情况。比如在例子:

nums=[1,2,3] , target=4

中,到达maximum[3]方法可能是,[2]放入了1,[1,1]放入了1,[1]放入了2,[]放入了3。则maximum[3]的值就是把这几种方案数累加起来。
所以核心式子maximum[ i ]+=maximum[ i - nums[ j ] ]中,nums[ j ]就是当前放入的物品重量,maximum[ i-nums[ j ] ] 就是上一步状态的方案数。内层循环是遍历nums[ j ],看有哪些物品重量符合、可放入。
加条件maximum[ i ] + maximum[ i-nums[ j ] ] <INT_MAX 是因为C++中会溢出。

	int combinationSum4(vector<int>& nums, int target) {
   
   
        vector<int> maximum(target+1,0);
        maximum[0] = 1;
        sort(nums.begin(),nums.end());
        for(int i=1;i<=target;i++){
   
   
            for
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值