LeetCode动态规划(九):完全背包(初级)

news2025/2/3 13:01:10

学习目标:

理解完全背包和0-1背包遍历顺序的区别


学习内容:

15. LeetCode377. 组合总和 Ⅳicon-default.png?t=N0U7https://leetcode.cn/problems/combination-sum-iv/

16. 爬楼梯(进阶班版)

17. LeetCode322. 零钱兑换icon-default.png?t=N0U7https://leetcode.cn/problems/coin-change/

18. LeetCode279. 完全平方数icon-default.png?t=N0U7https://leetcode.cn/problems/perfect-squares/


学习产出:

独立解决以上题目

15. LeetCode377. 组合总和 Ⅳ

 

思路:本题和零钱兑换II是同一类型的题,换汤不换药
注意:顺序不同的序列视作不同的组合,因此是求排列数(元素是有序的)而不是组合数

1.dp[i]:组成i的排列个数
2.dp[i]+=dp[i-nums[j]]:只要能够获取到nums[j],dp[i-nums[j]]是dp[i]的一部分
3.初始化dp:dp[0]=1,这样递推其他数值时才有基础,其他数值初始化为0,这样才不会影响累加值
4.遍历顺序:本质上就是对于每个容量i,用nums里所有元素去组合,从最基础的开始。比如说1个1组成1,2个1组成2,1个2组成2……
  4.1组合数:外层物品,内层容量
  4.2排列数:外层容量,内层物品(因为物品有顺序,顺序不同组合不同,所以我们在计算每个容量的方法数时,要把每个元素每种顺序都考虑到)
  4.3 eg.如果是外层遍历物品内层遍历容量,在计算dp[4]时,就会出现只有组合{1,3}而没有{3,1},因为3只会出现在1后面
class Solution {
public:
    int combinationSum4(vector<int>& nums, int target) {
        //dp[i]:组成i的排列个数
        vector<int>dp(target+1);
        //初始化dp
        dp[0]=1;
        //完善dp
        for(int i=0;i<=target;i++){
            for(int j=0;j<nums.size();j++){
                //防止溢出
                if(i-nums[j]>=0&&dp[i]<=INT_MAX-dp[i-nums[j]]){
                    //在组成i-nums[j]的基础上,用nums[j]填补,从而累加相应的方法数
                    //在组成dp[4]时:
                    //用1填补dp[3]:{1}+{1,2},{1}+{2,1},{1}+{1,1,1},{1}+{3}
                    //用2填补dp[2]:{2}+{1,1},{2}+{2}
                    //用3填补dp[1]:{3}+{1}
                    //不用去管dp[1],dp[2],dp[3]是怎么组成的,但是可以确定1可以出现在3后面了
                    //组成不同的i时,我们只遍历了一次nums里的所有元素,因此不会有重复排列出现
                    dp[i]+=dp[i-nums[j]];
                }
            }
        }
        return dp[target];
    }
};

16. 爬楼梯(进阶班版)

改为:一步1个台阶、2个台阶、3个台阶、4个台阶……直到m个台阶(每一阶可以重复使用),求到达楼顶的总方法数。
理解:台阶就是物品,楼顶就是背包,本题被改编成了完全背包问题
1.dp[i]:爬到第i个台阶的方法数
2.dp[i]+=dp[i-j]:加入当前要走j个台阶,那么dp[i-j]就是dp[i]的一部分(从dp[i-1]累加到dp[i-j]),因为一步可以跨1~j个台阶
3.初始化dp:dp[0]是基础数值,由其推得其他dp值,所以dp[0]=1
4.遍历顺序:外背包,内物品。比如{1,2,1}和{1,1,2}实际上是不同的方法,其实就是求排列个数
int climbStairs(int m,int n){
    //dp[i]:爬到第i个台阶的方法数
    vector<int>dp(n+1);
    //初始化dp
    dp[0]=1;
    //完善dp
    for(int i=0;i<=n;i++){
        for(int j=1;j<=i;j++){//从1个台阶开始累加
            dp[i]+=dp[i-j];
        }
    }
    return dp[n];
}

17. LeetCode322. 零钱兑换

思路:
1.dp[j]:组成j的最少硬币数
2.dp[j]=min(dp[j],dp[j-coins[i]]+1):组成j-coins[i]最少的硬币数+coins[i]这枚硬币
3.初始化dp:dp[0]=0
4.遍历顺序:外物品内背包,外背包内物品都可以。本题只是求硬币个数,所以无论硬币面额有序还是无序都不影响。

外物品内背包:
class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        //dp[j]:组成j的最少硬币数
        vector<int>dp(amount+1,INT_MAX-1);//不影响最小值判断
        //初始化dp
        dp[0]=0;
        //完善dp
        for(int i=0;i<coins.size();i++){
            for(int j=coins[i];j<=amount;j++){
                dp[j]=min(dp[j],dp[j-coins[i]]+1);
            }
        }
        return dp[amount]==INT_MAX-1?-1:dp[amount];
    }
};

外背包内物品:
class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        vector<int>dp(amount+1,INT_MAX-1);
        dp[0]=0;
        for(int i=0;i<=amount;i++){
            for(int j=0;j<coins.size();j++){
                if(i-coins[j]>=0)dp[i]=min(dp[i],dp[i-coins[j]]+1);
            }
        }
        return dp[amount]==INT_MAX-1?-1:dp[amount];
    }
};

18. LeetCode279. 完全平方数

思路:
1.dp[i]:和为i的完全平方数的最少数量
2.dp[i]=min(dp[i],dp[i-j*j]+1)
3.初始化dp:vector<int>dp(n+1,INT_MAX-1),dp[0]=0
4.遍历顺序:由于是求个数,所以无论哪种顺序都可以
class Solution {
public:
    int numSquares(int n) {
        //dp[i]:和为i的完全平方数的最少数量
        vector<int>dp(n+1,INT_MAX-1);
        //初始化dp
        dp[0]=0;
        //完善dp
        for(int i=1;i<=n;i++){
            for(int j=1;j*j<=i;j++){
                dp[i]=min(dp[i],dp[i-j*j]+1);
            }
        }
        return dp[n]==INT_MAX?-1:dp[n];
    }
};
j^2不是j的平方,而是j异或2

总结:题目要我们返回什么结果,动态规划表就表达什么意思。注意遍历顺序:如果是求组合数,就外物品内背包;如果是求组合数,就外背包内物品。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/192716.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

winform发布功能附加dll、db、xml、json等文件

我们日常进行程序的更新升级可能会用到winform的发布功能&#xff0c;但有些文件可能会无法伴随着发布一同发布出去或者每次发布后文件的数据被覆盖&#xff0c;下面一起看一下怎么解决&#xff1a; winform发布功能参考我另一篇文章https://blog.csdn.net/qq_39569480/articl…

筑基四层 —— 详解三子棋和扫雷

目录 一.修炼必备 二.三子棋详解 三.扫雷详解 四.三子棋和扫雷的完整代码 &#xff01;&#xff01;&#xff01;恭喜你&#xff0c;成功突破至筑基四层&#xff01;&#xff01;&#xff01; 一.修炼必备 1.入门必备&#xff1a;VS2019社区版&#xff0c;下载地址&#xff…

leetcode51,52 N皇后相关(回溯方法)

题目1&#xff1a;N皇后 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff0c;返回所有不同的 n 皇后问题…

入职一年,那个准的下班的人,比我先升职了...

最近心态崩了。 和我同期一道进公司的人又升了一级&#xff0c;可是明明大家在进公司时&#xff0c;他不论是学历还是工作经验&#xff0c;样样都不如自己&#xff0c;眼下不过短短的两年时间便一跃在自己的职级之上&#xff0c;这着实让我有几分不甘心。 我想不明白&#xff…

谈谈Linux epoll惊群问题的原因和解决方案

近期排查了一个问题&#xff0c;epoll惊群的问题&#xff0c;起初我并不认为这是惊群导致&#xff0c;因为从现象上看&#xff0c;只是体现了CPU不均衡。一共fork了20个Server进程&#xff0c;在请求负载中等的时候&#xff0c;有三四个Server进程呈现出比较高的CPU利用率&…

OpenCV 图像平滑处理

本文是OpenCV图像视觉入门之路的第10篇文章&#xff0c;本文详细的在图像上面进行了图像均值滤波、方框滤波 、高斯滤波、中值滤波、双边滤波、2D卷积等操作。 OpenCV 图像平滑处理目录 1 均值滤波 2 方框滤波 3 高斯滤波 4 中值滤波 5 双边滤波 6 2D卷积(自定义…

电子技术——分立MOS放大电路

电子技术——分立MOS放大电路 有了前两节的学习&#xff0c;即三种放大器配置和偏置方法之后&#xff0c;我们可以通过现成的分立晶体管、电阻、电容等搭建分立MOS放大电路。 DC偏置基本结构 在本节我们选用的DC偏置基本结构是如图所示的源极恒流源的偏置方案&#xff0c;下图…

用#define宏实现Add函数

✋作者&#xff1a;阿润菜菜 &#x1f4d6;专栏&#xff1a;C语言 我们知道#define宏是一种非常暴力的替换&#xff0c;宏定义会在程序编译预处理阶段在调用宏的位置进行文本内容的直接替换&#xff0c;因此我们在使用宏定义实现Add加法函数时就要注意一些可能会报错的问题。 …

第九层(10):STL之函数对象

文章目录前情回顾函数对象概念特点谓词概念内建函数对象分类算术仿函数关系仿函数逻辑仿函数下一座石碑&#x1f389;welcome&#x1f389; ✒️博主介绍&#xff1a;一名大一的智能制造专业学生&#xff0c;在学习C/C的路上会越走越远&#xff0c;后面不定期更新有关C/C语法&a…

你是如何学习 Java 的?

每一个行业中能成为大佬的人&#xff0c;一定都有他自己一套具有独到见解的方法...... 这个问题我很有发言权&#xff0c;从刚毕业做Java实习生月薪2k&#xff0c;到现在干了5年Java开发月薪43k&#xff0c;一直都在保持不断学习的状态。以我个人的经验来看&#xff0c;一个程…

视频分割新范式:视频感兴趣物体实例分割 VOIS

1. 背景视频中物体分割是视频理解的基础算法&#xff0c;也是对淘宝商品视频分析和加工所依赖的重要能力。传统的视频分割任务一般分为两种类型&#xff1a;一种是VOS&#xff08;Video Object Segmentation&#xff09;&#xff0c;该任务需要在第一帧给出物体的初始分割标注&…

Linux系列 目录和文件管理

作者简介&#xff1a;一名在校云计算网络运维学生、每天分享网络运维的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 简介 本章重点 一.检查文本内容 ​编辑 1.cat命令——显示并…

MySQL分表查询之Merge存储引擎实现

概念介绍 MySQL 分表之后怎么进行联合查询&#xff1f;用有表数量限制的 union all&#xff0c;还是汇总到一张表再查询&#xff0c;亦或用Sphinx&#xff08; 高性能SQL全文检索引擎 &#xff09;&#xff1f; 在这篇文章里&#xff0c;介绍使用 Merge [mɜːrdʒ] 存储引擎…

浅读人月神话(2)

读书笔记&#xff1a;今日翻书浅读&#xff0c;从《为什么巴比伦塔会失败》开始至《干将莫邪》结束&#xff0c;巴比伦塔的建造对当下项目推进有广泛借鉴意义&#xff0c;今天这几个章节在PMBOK中有一些可以互相对照学习的内容&#xff0c;《为什么巴比伦塔会失败&#xff1f;》…

荔枝派 zero 使用 Jlink 调试

Jlink 所谓硬件版本&#xff0c;就是这个调试器的硬件是第几代&#xff0c;我手上的这个是 V8 所谓固件版本&#xff0c;就是这个调试器主芯片中内置的软件是什么版本&#xff0c;我刷入的是 J-Link ARM V8 compiled Nov 28 2014 13:44:46 所谓 Jlink 工具版本&#xff0c;就…

记录--原生 canvas 如何实现大屏?

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 前言 可视化大屏该如何做&#xff1f;有可能一天完成吗&#xff1f;废话不多说&#xff0c;直接看效果&#xff0c;线上 Demo 地址 lxfu1.github.io/large-scree…。 看完这篇文章(这个项目)&#xff…

在线支付系列【13】微信支付之签名验签流程分析

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 文章目录前言签名生成签名验证总结前言 在上篇文档中&#xff0c;我们简单实现了对接微信支付的几个接口。了解到wechatpay-apache-httpclient框架自动实现了签名和验签&#xff0c;接下来跟踪下源码&a…

LeetCode-136. 只出现一次的数字

目录题目分析哈希集位运算题目来源 https://leetcode.cn/problems/single-number/ 题目分析 题目有个条件可谓相当重要&#xff0c;即凡重复的元素最多重复一次&#xff08;原话&#xff1a;给定一个非空整数数组&#xff0c;除了某个元素只出现一次以外&#xff0c;其余每个…

详解Mybatis-Plus中分页插件PaginationInterceptor, MybatisPlusInterceptor在SpringBoot中的使用

文章目录1. 描述1.1 MybatisPlusInterceptor1.2 InnerInterceptor2. 实现2.1 不带条件的分页查询2.2 带条件的分页查询2.3 简述Page类3. 注意事项1. 描述 1.1 MybatisPlusInterceptor 我们在开发的过程中&#xff0c;经常会遇到分页操作&#xff0c;其分为逻辑分页和物理分页…

Gif动态图片如何用静图制作?教你静图合成动图的方法

gif动图如何制作&#xff1f;相信对于gif动图大家都不陌生&#xff0c;在平时的聊天软件中、公众号文章中都可以看到。那么&#xff0c;要如何制作gif动图呢&#xff1f;下面&#xff0c;就给教大家两个在线gif制作&#xff08;https://www.gif.cn/&#xff09;的方法&#xff…