动态规划day38|322. 零钱兑换(背包满了吗?最小值怎么表示?)、279. 完全平方数、139. 单词拆分、多重背包要点、背包问题大总结

动态规划day38|322. 零钱兑换(背包满了吗?最小值怎么表示?)、279. 完全平方数、139. 单词拆分、多重背包要点、背包问题大总结

  • 322. 零钱兑换
  • 279. 完全平方数
  • 139. 单词拆分
  • 多重背包要点
  • 背包问题大总结

322. 零钱兑换

给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。

计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1

你可以认为每种硬币的数量是无限的。

示例 1:

输入:coins = [1, 2, 5], amount = 11
输出:3
解释:11 = 5 + 5 + 1

示例 2:

输入:coins = [2], amount = 3
输出:-1

示例 3:

输入:coins = [1], amount = 0
输出:0

提示:

  • 1 <= coins.length <= 12
  • 1 <= coins[i] <= 231 - 1
  • 0 <= amount <= 104

第一次做的时候,我不知道该怎么去表示背包已经满了以及什么才是最小值

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

首先回答我一开始的两个疑问:

  • 怎么去表示背包已经满了?
    首先我们整体过一遍背包的过程:对于第一个物品,从dp[coins[i]]开始,它是在dp[0]的基础上加的,所以它必然是满的,然后之后一个背包就是在dp[coins[i]]的基础上加的,所以它也是满的……就这样不断迭代推进,像多米诺骨牌一样,要不就装不了,要不就是装满的。如果从中间看确实难看出来,但是从开头的几个,如当i=0时的dp[1]、dp[2],就明确的知道:只要dp[j]有值,那么它就是满的
  • 什么才是最小值?
    这就是递归函数的作用,一般最大值要有max,最小值要有min,求个数问题则是求和
    为什么这样(dp[j]=min(dp[j-coins[i]]+1,dp[j])) 就是最小值?我们还是一样,从开头开始看,当新物品纳入的时候,我们就要考虑是加入新物品“好”,还是不加新物品“好”,每回都是选两者中最小的,那么到了后面,自然而然就是最小值了。

易错点

  • 初始化:由于是求min,所以必须初始化为INT_MAX,绝不能简单的赋为0,否则0会覆盖真正的值。
if(dp[j-coins[i]]!=INT_MAX)dp[j]=min(dp[j-coins[i]]+1,dp[j]);

这里的if条件不可少,如果没有它,那么dp[j-coins[i]]+1就会超过INT_MAX,从而引发异常

  if(dp[amount]==INT_MAX) return -1;

当不能凑出amout的时候,dp[amount]的值还是原来初始化的值。至于为什么,你可以借助开头的几个dp来理解。

279. 完全平方数

给你一个整数 n ,返回 和为 n 的完全平方数的最少数量

完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,14916 都是完全平方数,而 311 不是。

示例 1:

输入:n = 12
输出:3
解释:12 = 4 + 4 + 4

示例 2:

输入:n = 13
输出:2
解释:13 = 4 + 9

提示:

  • 1 <= n <= 104
class Solution {
public:vector<int> pingFangShu(int n){vector<int> nums(n);for(int i=1;;i++){if(i*i<=n)nums.push_back(i*i);elsebreak;}return nums;}int numSquares(int n) {vector<int> dp(n+1,INT_MAX);dp[0]=0;vector<int> nums=pingFangShu(n);for(int i=0;i<nums.size();i++)for(int j=nums[i];j<=n;j++)if(dp[j-nums[i]]!=INT_MAX)dp[j]=min(dp[j-nums[i]]+1,dp[j]); return dp[n];}
};

这样的写法是可以的,但是超出了力扣的时间限制。上面的是单独生成“物品”,选择只好在for循环里面边遍历边生成了,代码如下:

class Solution {
public:int numSquares(int n) {vector<int> dp(n+1,INT_MAX);dp[0]=0;for(int i=1;i*i<=n;i++)for(int j=i*i;j<=n;j++)if(dp[j-i*i]!=INT_MAX)dp[j]=min(dp[j-i*i]+1,dp[j]); return dp[n];}
};

原理和322基本相同。

139. 单词拆分

给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s 则返回 true

**注意:**不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。

示例 1:

输入: s = “leetcode”, wordDict = [“leet”, “code”]
输出: true
解释: 返回 true 因为 “leetcode” 可以由 “leet” 和 “code” 拼接成。

示例 2:

输入: s = “applepenapple”, wordDict = [“apple”, “pen”]
输出: true
解释: 返回 true 因为 “applepenapple” 可以由 “apple” “pen” “apple” 拼接成。
注意,你可以重复使用字典中的单词。

示例 3:

输入: s = “catsandog”, wordDict = [“cats”, “dog”, “sand”, “and”, “cat”]
输出: false

提示:

  • 1 <= s.length <= 300
  • 1 <= wordDict.length <= 1000
  • 1 <= wordDict[i].length <= 20
  • swordDict[i] 仅由小写英文字母组成
  • wordDict 中的所有字符串 互不相同
class Solution {
public:bool wordBreak(string s, vector<string>& wordDict) {unordered_set<string> wordSet(wordDict.begin(), wordDict.end());vector<bool> dp(s.size() + 1, false);dp[0] = true;for (int j = 1; j <= s.size(); j++) {   // 遍历背包for (int i = 0; i < j; i++) {       // 遍历物品string word = s.substr(i, j - i); //substr(起始位置,截取的个数)if (wordSet.find(word) != wordSet.end() && dp[i]) {dp[j] = true;}}}return dp[s.size()];}
};

本题难度较高,一刷可放过

多重背包要点

  • 有N种物品和一个容量为W 的背包。第 i 种物品最多有 Mi 件可用,每件耗费的空间是Ci ,价值是 Vi ,求价值总和最大。
  • **多重背包和01背包是非常像的:**每件物品最多有Mi件可用,把Mi件摊开,其实就是一个01背包问题了,即:
for (int i = 0; i < n; i++) {while (nums[i] > 1) { // 物品数量不是一的,都展开weight.push_back(weight[i]);value.push_back(value[i]);nums[i]--;}}vector<int> dp(bagWeight + 1, 0);for(int i = 0; i < weight.size(); i++) { // 遍历物品,注意此时的物品数量不是nfor(int j = bagWeight; j >= weight[i]; j--) { // 遍历背包容量dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);}}return dp[bagWeight] 
}
  • 多重背包在面试中基本不会出现

背包问题大总结

img

(这个图是代码随想录知识星球成员海螺人所画)

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

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

相关文章

后端-项目创建与sql

1.创建文件 1.在webcontent下创建.html文件 2. 在java resources下创建包&#xff0c;右键包创建servlet服务生.(要是创建普通的类&#xff0c;里面的注解里的东西不能重复&#xff09; 注意&#xff1a;class的名字要和文件名一样&#xff0c;注解里的servlet是独一无二的。 …

最新 idea 2024 入门使用详细教程

IntelliJ IDEA&#xff1a;这是一款由JetBrains公司开发的Java集成开发环境&#xff08;Integrated Development Environment&#xff09;&#xff0c;被广泛认为是目前Java开发者最好的集成开发工具之一。它支持Java、Groovy、Kotlin等多种编程语言&#xff0c;并且提供了丰富…

HCIA--实验十七:EASY IP的NAT实现

一、实验内容 1.需求/要求&#xff1a; 通过一台PC&#xff0c;一台交换机&#xff0c;两台路由器来成功实现内网访问外网。理解NAT的转换机制。 二、实验过程 1.拓扑图&#xff1a; 2.步骤&#xff1a; 1.PC1配置ip地址及网关&#xff1a; 2.AR1接口配置ip地址&#xff1…

Java免税商品优选商城:Spring Boot实战

第二章 系统开发关键技术 2.1 JAVA技术 Java主要采用CORBA技术和安全模型&#xff0c;可以在互联网应用的数据保护。它还提供了对EJB&#xff08;Enterrise JavaBeans&#xff09;的全面支持&#xff0c;java servlet AI&#xff0c;JS&#xff08;java server ages&#xff09…

Tomcat中BIO和NIO的区别(Tomcat)

BIO Tomcat中BIO的模型和理论很简单&#xff0c;例图如下 1.Acceptor线程死循环阻塞接收客户端的打过来的socket请求 2.接收到请求之后打包成一个SocketProcessor&#xff08;Runnable&#xff09;&#xff0c;扔到线程池中读取/写入数据 参数配置 1.Acceptor默认线程是1&#…

2024年1月Java项目开发指南17:自动接口文档配置

Knife4j 文档 &#xff1a;https://doc.xiaominfo.com/ 有能力的建议自己去看文档配置&#xff0c;本文仅做参考&#xff0c;因为官方文档会更新&#xff0c;本文不会&#xff0c;以后说不定本文就过时了。 ok&#xff0c;我们继续。虽然本文是2024年1月Java项目开发指南17&…

JVM面试题-说一下JVM主要组成部分及其作用

总体来说&#xff0c;方法区和堆是所有线程共享的内存区域&#xff1b;而虚拟机栈、本地方法栈和程序计数器的运行是线程私有的内存区域&#xff0c;运行时数据区域就是我们常说的JVM的内存。 类加载子系统&#xff1a;根据给定的全限定名类名(如&#xff1a;java.lang.Object…

使用Kong开源API网关的保姆级教程

什么是Kong? Kong是一个开源的、云原生、高性能的API网关,可以轻松地为任何服务提供管理、保护和扩展。它提供了一个可扩展的插件生态系统,可以满足各种各样的需求,如身份验证、授权、限流、监控等。 安装Kong 1. 环境准备 操作系统: CentOS、Ubuntu等主流Linux发行版D…

微信小程序IOS真机调试-onPullDownRefresh和onReachBottom不生效

切换真机调试2.0版本 勾选JS编译成ES5 如果使用了 uniapp&#xff0c;这里也需要勾选 重新启动

【Proteus单片机仿真】基于51单片机的循迹小车避障+气体传感器和温度传感器系统

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 开机即两个直流电机运转&#xff0c;然后三个气体传感器&#xff0c;如果超过阈值&#xff0c;即蜂鸣器报警&#xff1b; 超声波传感器&#xff0c;如果检测到障碍&#xff0c;电机停止&#xff1…

深度学习02-pytorch-06-张量的形状操作

在 PyTorch 中&#xff0c;张量的形状操作是非常重要的&#xff0c;可以让你灵活地调整和处理张量的维度和数据结构。以下是一些常用的张量形状函数及其用法&#xff0c;带有详细解释和举例说明&#xff1a; 1. reshape() 功能: 改变张量的形状&#xff0c;但不改变数据的顺序…

[Redis][List]详细讲解

目录 0.前言1.常用命令1.LPUSH / RPUSH2.LPUSHX / RPUSHX3.LRANGE4.LPOP / RPOP5.LINDEX6.LINSERT7.LLEN8.LREM9.LTRIM10.LSET 2.阻塞版本命令0.是什么&#xff1f;1.BLPOP / BRPOP 3.内部编码(旧版本&#xff0c;仅供参考)1.ziplist(压缩链表)2.linkedlist(链表)3.quicklist(快…

TK72A12N1 N沟道功率MOSFET 工业控制领域的高性能功率开关

TK72A12N1产品特性&#xff1a; 漏源电压&#xff08;Vdss&#xff09;&#xff1a;120V&#xff0c;这意味着该器件在正常工作时&#xff0c;漏极和源极之间所能承受的最大电压为 120V。如果超过这个电压&#xff0c;可能会导致器件损坏。 漏极电流&#xff08;Id&#xff0…

基于SpringBoot和Vue框架的医保管理系统的设计与实现

文未可获取一份本项目的java源码和数据库参考。 1.研究的主要内容与方法 &#xff08;1&#xff09;主要内容 医保管理系统采用B/S模式进行开发&#xff0c;采用Springboot框架、VUE技术、Idea为环境、MySQL为数据库开发。主要功能有&#xff1a;个人资料管理、投保用户管理、…

C++ 把字符串转换成整数 (atoi) - 力扣(LeetCode)

点击链接即可查看&#xff1a;LCR 192. 把字符串转换成整数 (atoi) - 力扣&#xff08;LeetCode&#xff09; 一、题目 请你来实现一个 myAtoi(string s) 函数&#xff0c;使其能将字符串转换成一个 32 位有符号整数&#xff08;类似 C/C 中的 atoi 函数&#xff09;。 函数 my…

剩余参数运算符的babel转义配置

记一次生产构建的报错 uncaught syntaxerror: unexpected token ... 背景 在处理展示markdown文本功能&#xff0c;并且其中的代码高亮功能时&#xff0c;引入了两个第三发的依赖包marked 和 highlight.js &#xff0c;本地功能调试正常之后&#xff0c;一如即往的没有build…

基于51单片机的汽车倒车防撞报警器系统

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 本课题基于微控制器控制器&#xff0c; 设计一款汽车倒车防撞报警器系统。 要求&#xff1a; 要求&#xff1a;1.配有距离&#xff0c; 用于把车和障碍物之间的距离信号送入控制器。 2.配有报警系…

【漏洞复现】金斗云 HKMP download 任意文件读取漏洞

免责声明&#xff1a; 本文内容旨在提供有关特定漏洞或安全漏洞的信息&#xff0c;以帮助用户更好地了解可能存在的风险。公布此类信息的目的在于促进网络安全意识和技术进步&#xff0c;并非出于任何恶意目的。阅读者应该明白&#xff0c;在利用本文提到的漏洞信息或进行相关测…

[产品管理-32]:NPDP新产品开发 - 30 - 文化、团队与领导力 - 领导力与团队的可持续发展

目录 一、团队领导的领导力 1.1 领导力 1、领导力的定义 2、领导力的重要性 3、领导力的构成要素 4、如何提升领导力 1.2 情商 二、虚拟团队 1、团队定义与特征 2、团队优势 3、团队挑战与应对策略 三、可持续发展 四、团队管理和领导力中的度量指标 4.1 激励创新…

SpringBoot环境配置(Spring Boot Profile)

一、介绍 在Spring Boot中&#xff0c;spring.profiles 配置用于定义不同环境下的配置文件。这使得应用可以在不同的环境中使用不同的配置&#xff0c;比如开发环境、测试环境和生产环境等。这种方式可以避免在代码中硬编码配置信息&#xff0c;并且能够更灵活地管理应用的环境…