算法训练营DAY44|518. 零钱兑换 II、377. 组合总和 Ⅳ

news2024/11/27 21:49:48

这两道题是对于完全背包题型的另一个维度,都是求解给定背包容量求装满背包最多有几种方法的题目。两道题十分相像,但在遍历顺序上却又有着极其微妙的差别。

518. 零钱兑换 II - 力扣(LeetCode)icon-default.png?t=MBR7https://leetcode.cn/problems/coin-change-ii/零钱兑换II是完全背包中的装满背包有几种方法的题,而我们以前做过的目标和很是相像,那个需要限定物品只有一个而这道题的区别仅仅是不限定物品的数量。

dp数组的含义:还是根据动规的五部曲来分析,首先dp数组的含义一定是容量为j时候,可以有多少种方法填满背包。

递推公式:递推公式与目标和那道题是一样的。dp【j】+=dp【j-nums【i】】虽然那期已经讲过了,递推公式是如何得到了,但是在本期我想对此再作进一步的补充说明。我们还是以j=5来举例,实际上可以将该递推公式想像成dp【5】=dp【5-nums【0】】+dp【5-nums【1】】+dp【5-nums【2】】+......这样展开来看是不是就更容易理解了,就是先假定我们一定会加入该物品,然后我们再看背包容量j减掉当前物品的重量后,还有几种方法。因为dp【j】所代表的就是当前容量几种方法,所以减掉物品重量后,我们可以用到之前求得的dp来累加起来。背包容量每扩大一点,所对应的填满方法个数,都需要用它之前的背包容量的方法来累加计算得到。

dp数组的初始化:我们之前就说果dp【0】=1,这是因为我们累加如果第一个数就是0,那么加到最后也还是0,其他非0的部分初始化为0,这是因为递推公式的缘故,是累加起来的,如果非0部分初始化不为0,累加时候会不准。换句话来说,累加取决的应该是当前容量之前的各个容量和,而并非受当前容量本身所影响。

遍历顺序:遍历顺序由于是完全背包模型的缘故,需要将背包正序遍历,以装入重复物品。至于是先遍历背包还是先遍历物品也是有讲究的。这道题我们通过测试用例可以看得出来,很明显测试用例都是组合,而非排列,也就是说我们求得的是无顺序的,{1,2}和{2,1}应该看成一种情况!我们这个时候应该先遍历物品后遍历背包,先锁定物品再装入背包这样的好处是,如果数组是{1,2}那么2一定会出现在1的后面被添加,而不是出现在前面,因为先遍历物品的缘故。如果是相反的先遍历背包,那么很有可能会在背包里同时出现{1,2}和{2,1}的情况。我认为这与递推公式也有一定的关系,如果是先遍历背包的话,那么锁定背包容量去遍历物品,当前的循环就可能出现以下情况,当背包容量为3,物品为{1,2},遍历到第一个物品,背包装物品1后根据递推公式是再加等于dp【3-1】,遍历到第2个物品时候,根据递推公式是再加等于dp【3-2】这就造成了我上面说的重复添加,也就是排列的情况了!这相当于二维数组中的同一层在一次填数时候,连续更新了背包!如果是先遍历物品再遍历背包的情况,那么当前里层循环只有装入当前遍历的物品和不装入两种情况,当前并不能加入其它物品,也就不会出现排列的情况,那有人说那你第二次加入物品呢?比如第一次加入1,第二次加入2呢?那不是和之前一样了吗?其实不然,因为第二次加入物品2,那在二维数组中相当于下一层填数了,并不影响上一层,别忘了一维数组是滚动数组。一个是同一层的连续更新,一个是一层一层的更新,是有区别的。

这就是我对遍历顺序的理解,我们也可以简记为求组合,先遍历物品,求排列,先遍历背包!!!

class Solution {
public:
    int change(int amount, vector<int>& coins) {
        vector<int>dp(amount+1,0);
        dp[0]=1;
        for(int i=0;i<coins.size();i++){
            for(int j=0;j<=amount;j++){
                if(j>=coins[i])
                dp[j]+=dp[j-coins[i]];
            }
        }
        return dp[amount];
    }
};

377. 组合总和 Ⅳ - 力扣(LeetCode)icon-default.png?t=MBR7https://leetcode.cn/problems/combination-sum-iv/这道题实际上的思路和上一道题完全一样,只不过这道题是求排列的。这里就不进行动规分析了!

我们只需要将遍历顺序改成我上面说的规律,使for循环的两层上下颠倒即可。

class Solution {
public:
    int combinationSum4(vector<int>& nums, int target) {
        vector<int>dp(target+1,0);
        dp[0]=1;
        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]];
            }
        }
        return dp[target];
    }
};

仍有一点需要注意,就是我们在判断部分还要写上dp[j]<INT_MAX-dp[j-nums[i]],这是因为测试用例中有出现两个数相加超过int承载范围的数字。但是我们不能直接写成dp【j】+dp【j-nums【i】】<INT_MAX,因为两个数相加太大它也会报错,所以我们要将一个数转移到等号右边,使它做差,这样就可以避免报错了!


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

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

相关文章

看完流浪地球2,这些功课你必须要补

昨天看了流浪地球2&#xff0c;里面的信息量太大了&#xff0c;回来补充了一些功课&#xff0c;这些知识&#xff0c;看完&#xff0c;才算对流浪地球2有了进一步了解。地球人的航天路径我们的太空航程是什么样子的呢&#xff1f;要从第二次世界大战开始。回形针计划&#xff1…

金仓数据库简单巡检与事务阻塞会话简单处理

查看KES版本信息 使用version函数查看 这种方式能详细显示信息 使用ksql查看 查看license有效期 查看实例启动时间和运行时长 查看实例启动时间 查看KES无故障运行时长 查看数据库列表 使用元命令\l查看 使用字典查看 查看数据库占用的磁盘空间 统计当前数据库所占的磁盘空…

chrome在爬虫中的使用

chrome浏览器使用方法介绍 学习目标 了解 新建隐身窗口的目的了解 chrome中network的使用了解 寻找登录接口的方法 1 新建隐身窗口 浏览器中直接打开网站&#xff0c;会自动带上之前网站时保存的cookie&#xff0c;但是在爬虫中首次获取页面是没有携带cookie的&#xff0c;这…

Wireshark TS | Packet Challenge 之 FTP 案例分析

前言 来自于 Sharkfest Packet Challenge 中的一个数据包案例&#xff0c;Sharkfest 是 Wireshark 官方组织的一年一度的大会&#xff0c;致力于在 Wireshark 开发人员和用户社区之间分享知识、经验和最佳实践。印象中早期是一年一次&#xff0c;近几年发展成一年两次&#xf…

【华为上机真题】工号不够用咋办

&#x1f388; 作者&#xff1a;Linux猿 &#x1f388; 简介&#xff1a;CSDN博客专家&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6;&#xff0c;Linux、C/C、云计算、物联网、面试、刷题、算法尽管咨询我&#xff0c;关注我&#xff0c;有问题私聊&#xff01; &…

2D测量 Metrology——

基本流程: 1,创建计量模型 create_metrology_model (MetrologyHandle) 2,设置计量模型的图像大小 set_metrology_model_image_size (MetrologyHandle, Width, Height) 3,将计量对象添加至计量模型中.(矩形,直线,圆,椭圆) add_metrology_object_rectangle2_measure  //矩形…

【高并发】- 指标介绍

什么是高并发 高并发系统有哪些关键指标 高并发系统介绍 本文主要讲解高并发系统的概念&#xff0c;在实际开发过程中为什么要使用高并发系统&#xff0c;相比于传统系统&#xff0c;能带来怎样的改变。 1.1 高并发介绍 高并发&#xff08;Hign Concurrency&#xff09;&#…

Linux常用命令——sed命令

在线Linux命令查询工具(http://www.lzltool.com/LinuxCommand) sed 功能强大的流式文本编辑器 补充说明 sed是一种流编辑器&#xff0c;它是文本处理中非常中的工具&#xff0c;能够完美的配合正则表达式使用&#xff0c;功能不同凡响。处理时&#xff0c;把当前处理的行存…

剖析“类和对象” (下) -------- CPP

学习完“类和对象”(上)【剖析“类和对象” (上) -------- CPP】和(中)【剖析“类和对象” (中) -------- CPP】&#xff0c;相信各位同学对CPP中类与对象的理解或多或少都加深了一点。 本篇博客将和大家一同再次学习CPP中类和对象的知识点&#xff0c;跟随本篇博客的脚步定能…

Java两大工具库:Commons和Guava(1)

您好&#xff0c;我是湘王&#xff0c;这是我的CSDN博客。值此新春佳节&#xff0c;我给您拜年啦&#xff5e;祝您在新的一年中所求皆所愿&#xff0c;所行皆坦途&#xff0c;展宏“兔”&#xff0c;有钱“兔”&#xff0c;多喜乐&#xff0c;常安宁&#xff01;Java的成功很大…

Kettle(8):删除组件

删除组件能够按照指定条件,将表中的数据删除。 1 需求 有以下一个文本文件,文本文件包含了要删除的两个用户id: id 392456197008193000 267456198006210000 需要使用Kettle将文本文件中两个ID对应的t_user1表的数据删除。 2 构建Kettle数据流图 效果图: 1 将文本文件输…

【算法突击】动态规划系列 (一)| 程序员面试 | 最大子数组和 | 最长递增子序列 | 最长公共子序列

【算法突击】动态规划系列 &#xff08;一&#xff09;| 程序员面试 | 最大子数组和 | 最长递增子序列 | 最长公共子序列 文章目录【算法突击】动态规划系列 &#xff08;一&#xff09;| 程序员面试 | 最大子数组和 | 最长递增子序列 | 最长公共子序列1. 最大子数组和1.1 题目…

C 语言零基础入门教程(十三)

函数指针 函数指针是指向函数的指针变量。 通常我们说的指针变量是指向一个整型、字符型或数组等变量&#xff0c;而函数指针是指向函数。 函数指针可以像一般函数一样&#xff0c;用于调用函数、传递参数。 函数指针变量的声明&#xff1a; typedef int (*fun_ptr)(int,i…

ATAC-seq分析:Annotating Peaks(9)

1. 注释开放区域 将已识别的无核小体区域与基因组特征&#xff08;如基因和增强子&#xff09;相关联通常很有趣。 一旦注释到基因或增强子的基因&#xff0c;我们就可以开始将 ATACseq 数据与这些基因的特征相关联。 &#xff08;功能注释、表达变化、其他表观遗传状态&#x…

瑞吉外卖实战

https://blog.csdn.net/weixin_43715214/category_12022798.html大佬记录项目介绍day01功能架构&#xff08;1&#xff09;用户层本项目中在构建系统管理后台的前端页面&#xff0c;我们会用到H5、Vue.js、ElementUI等技术。而在构建移动端应用时&#xff0c;我们会使用到微信小…

计算机网络连环炮40问

本文已经收录到Github仓库&#xff0c;该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等核心知识点&#xff0c;欢迎star~ Github地址&#xff1a;https://github.com/…

Day09 C++STL入门基础知识六——deque容器 构造函数-赋值操作-大小操作-插入删除-数据存储-排序操作【全面深度剖析+例题代码展示】

无人问津的日子&#xff0c;我为自己喝彩&#xff01; 文章目录1. 基本概念1.1 功能1.2 与vector区别1.3 图解1.4 内部工作原理1.5 deque 容器的迭代器也是支持随机访问的2. 构造函数2.1 函数原型2.2 代码展示2.3 测试结果2.4 小think2.4.1 小问题2.4.2 思路2.4.3 修改2.4.4 测…

从零开始的数模(六)python在高等数学和线性代数中的应用

科学计算设计数值计算和符号计算&#xff0c;在python中作基础数值计算用numpy和scipy工具库&#xff0c;作符号运算用sympy工具库 sympy工具库–符号运算 符号运算基本知识 1.利用symbols函数创建符号变量构造多个符号变量时中间以空格分隔 2.利用符号变量创建表达式 3.利用…

Hive整合HBase,操作HBase表

Hive over HBase原理 Hive与HBase利用两者本身对外的API来实现整合&#xff0c;主要是靠HBaseStorageHandler进行通信&#xff0c;利用 HBaseStorageHandler&#xff0c;Hive可以获取到Hive表对应的HBase表名&#xff0c;列簇以及列&#xff0c;InputFormat和 OutputFormat类&…

STS:Surround-view Temporal Stereo for Multi-view 3D Detection——论文笔记

参考代码&#xff1a;None 1. 概述 介绍&#xff1a;这篇文章提出的方法是对LSS中深度估计部分进行改进&#xff0c;其改进的点是在深度估计部分引入立体匹配去估计周视相机下的深度信息&#xff0c;其中立体匹配使用前后视频帧进行构建&#xff08;可以看作是时序信息的使用&…