当前位置: 首页 > news >正文

力扣 | 背包dp | 279. 完全平方数、518. 零钱兑换 II、474. 一和零、377. 组合总和 Ⅳ

文章目录

  • 一、279. 完全平方数
  • 二、518. 零钱兑换 II
  • 三、474. 一和零
  • 四、377. 组合总和 Ⅳ

一、279. 完全平方数

LeetCode:279. 完全平方数
在这里插入图片描述
朴素想法:
这个题目最简单的想法是,可以用 O ( n n ) O(n\sqrt{}n) O(n n)的动态规划解决,定义dp[i]表示整数i完全平方数的最少数量。

由于我们不太能知道都有哪些可以构成,我们直接枚举 k k k,且满足 k 2 < = i k^2<=i k2<=i,找出最小的即可。

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

问题抽象:
这个问题是否也能转化成 完全背包问题?

相当于 1 1 1~ n n n可以无限选择,达到背包容量n,并且使得放入的数最少。

我们可以定义 d p [ i ] [ j ] dp[i][j] dp[i][j] 表示达到j,能够选择 1 1 1~ i i i,所使用的最小数字,那么我们就可以像完全背包一样进行状态转移了。(注意这里i最大是 n \sqrt{}n n,因此时间复杂度也是 n n n\sqrt{n} nn

我们仔细看一下 可以发现,实际上和方法一就是循环调个位置。

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

那么,我们如何抽象问题为完全背包问题? 到目前为止,我们还不能直接进行问题抽象,而是看到题有类似的样子才做出完全背包的想法。

我们来看看,之前考虑过的问题,整数拆分、322. 零钱兑换、518. 零钱兑换 II 。

他们都是 有无限个"物品"可以选择这些物品组合成"背包"里的物品(无论是体积还是质量)最后需要达成一个目标

这个目标就是我们定义的状态、
这个物品就是我们要规定什么时候能包含的、
这个背包就是总的容量

比如这个完全平方数,我们要定义的状态是和为i的最少完全平方数的数量,我们要规定的物品是 1 1 1~ n \sqrt{n} n ,我们的最后容量就是n

不过我们需要注意的是,放入背包的物品没有顺序要求。

二、518. 零钱兑换 II

LeetCode:518. 零钱兑换 II
在这里插入图片描述
普通的完全背包问题,做到这里已经不需要优化了,直接写了,因为写的完全背包太多了。

完全背包问题更新:
不过完全背包要注意的是,从小往大来遍历,因为可以选择无限个,
dp[j - coins[i]]这个转移,表示的是容量为j的这个背包一部分用来装一个coins[i],其余部分就是dp[j - coins[i]]的部分,这个部分是可以包含coins[i]的。 我们来思考一下这个转移对不对?我们来把背包具象化,dp[j - coins[i]]个容量为j - coins[i]的不同背包,它们都是互不相同的,且都可能包含coins[i]因为coins[i]没有个数限制。然后我们把这些不同的背包都加上coins[i]这个物品,这几个背包不同的! 不信你拿出来看看,一个一个比!这一部分是至少包含一个coins[i]的可能性。而之前的dp[j]是不包含任何coins[i]的可能性。

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 = coins[i]; j <= amount; ++ j){dp[j] = dp[j] + dp[j - coins[i]];}}return dp[amount];}
};

三、474. 一和零

LeetCode:474. 一和零
在这里插入图片描述
这是一个0-1背包问题,也就是,这里每个元素只能选择一次。
这里可以定义两维来表示01的个数,dp[i][j]表示最多有i0j1的最长子集长度。

那么我们来考虑当前考虑字符串时,我们提取出它的0的个数和1的个数,假如分别为kp,那么就可以进行一次转移。

dp[u][i][j] = max(dp[u - 1][i -k][j - p], dp[u - 1][i][j]

class Solution {
public:int findMaxForm(vector<string>& strs, int m, int n) {vector<vector<vector<int>>> dp(strs.size() + 1, vector<vector<int>>(m + 1, vector<int>(n + 1, 0)));for(int i = 1; i <= strs.size(); ++ i){int zero_num = Get(strs[i - 1]);int one_num = (int) strs[i - 1].size() - zero_num;for(int j = 0; j <= m; ++ j){for(int k = 0; k <= n; ++ k){dp[i][j][k] = dp[i - 1][j][k];if(j >= zero_num && k >= one_num)dp[i][j][k] = max(dp[i][j][k], dp[i - 1][j - zero_num][k - one_num] + 1);}}}return dp[strs.size()][m][n];}
private:int Get(string & s){int ans = 0;for(auto ch : s){if(ch == '0') ++ ans;}return ans;}
};

空间优化:

class Solution {
public:int findMaxForm(vector<string>& strs, int m, int n) {vector<vector<int>> dp(m + 1, vector<int>(n + 1));for(int i = 1; i <= strs.size(); ++ i){int zero_num = Get(strs[i - 1]);int one_num = (int) strs[i - 1].size() - zero_num;for(int j = m; j >= zero_num; -- j){for(int k = n; k >= one_num; -- k){dp[j][k] = max(dp[j][k], dp[j - zero_num][k - one_num] + 1);}}}return dp[m][n];}
private:int Get(string & s){int ans = 0;for(auto ch : s){if(ch == '0') ++ ans;}return ans;}
};

我们来看看空间优化先后的状态转移的区别,实际上空间优化后,它直接继承了所有的前面的部分。

空间优化前很容易出错:
容易写成这样:

for(int j = zero_num; j <= m; ++ j){for(int k = one_num; k <= n; ++ k){dp[i][j][k] = max(dp[i - 1][j][k], dp[i - 1][j - zero_num][k - one_num] + 1);}
}

仔细思考发现转移方程确实没错,dp[i][j][k]表示考虑前i个字符串,0的个数最多为j1的个数最多为k,我们单独拿出来strs[i - 1],其余部分是dp[i - 1][j - zero_num][k -one_num]这一部分也是对的定义,那么转移也是对的。那么问题出在哪呢?

问题出在,当 j < z e r o _ n u m j < zero\_num j<zero_num k < o n e _ n u m k < one\_num k<one_num时,我们没有进行状态转移,换句话说,没有考虑当当前背包容量不能容纳strs[[i - 1]时,可以放strs[0] ~ strs[i - 2],也就是说必须直接继承,因为考虑前i个字符串确实有东西可以放的话 你不继承就错了。

四、377. 组合总和 Ⅳ

LeetCode:377. 组合总和 Ⅳ
在这里插入图片描述
这里和零钱兑换II的区别在于,这里的元素是有顺序的。 零钱兑换II没有顺序,就像背包内放物品是没有顺序的。那么我们仅仅使用背包的思想肯定是不能得到答案的,毕竟这里有放入顺序。

既然有顺序,那我们枚举每一个容量的最后一个物品就能保证这几个的放法都不一样了,因此可以这样进行状态转移。

也就是说,我们从最小容量开始枚举它最后一个物品,来保证它放的内容不一样,然后依次枚举容量,你会发现我们保证了每个容量的最后一个都不一样,这确实能做到有顺序的问题。(排列问题,毕竟小容量也考虑了这些物品,这些物品可以无限次放。)

class Solution {
public:int combinationSum4(vector<int>& nums, int target) {vector<long long> dp(target + 1);dp[0] = 1;int mod = INT_MAX;for(int i = 1; i <= target; ++ i){for(int j = 0; j < nums.size(); ++ j){if(i >= nums[j])dp[i] = (dp[i] + dp[i - nums[j]]) % mod;;}}return dp[target];}
};

题目中有一个坑的,就是说答案在int范围内,但是中间结果可能爆int,这里有两个解决方案:
(1)使用long long然后取模,long long是为了保证中间结果的计算爆int,取模是将结果映射到int范围内,对于答案来说必然是没有错误的,因为答案本身就在int范围内,映射过后还是本身。

(2)对于爆int的进行摒弃,原因在于,答案不可能用它来转移,这种背包不可能转移到其他人身上,不然会产生链锁反应,即使是转移了,那些人也必然对答案没有贡献,不然就爆int了。

        for (int i = 1; i <= target; i++) {for (int& num : nums) {if (num <= i && dp[i - num] < INT_MAX - dp[i]) {dp[i] += dp[i - num];}}}

相关文章:

力扣 | 背包dp | 279. 完全平方数、518. 零钱兑换 II、474. 一和零、377. 组合总和 Ⅳ

文章目录 一、279. 完全平方数二、518. 零钱兑换 II三、474. 一和零四、377. 组合总和 Ⅳ 一、279. 完全平方数 LeetCode&#xff1a;279. 完全平方数 朴素想法&#xff1a; 这个题目最简单的想法是&#xff0c;可以用 O ( n n ) O(n\sqrt{}n) O(n ​n)的动态规划解决&#x…...

【ECMAScript性能优化的技巧与陷阱】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…...

Swift实时监听判断是否连接有网络WIFI和蜂窝数据

本章节讲解如何使用swift连接网络&#xff0c;实时的监听到网络的状态&#xff0c;在主界面中进行调用&#xff0c;网络包含Wi-Fi 和 蜂窝。 1.封装一个判断是否有网络的类 2.在封装类注册通知 3.主界面接收注册通知&#xff0c;并且调用封装的网络类 4.成功测试&#xff0c;有…...

(三)Flink Source 数据源

Flink 数据源主要分为内置数据源和第三方数据源。其中内置数据源包含文件、Socket 连接、集合类型数据等,不需要引入其它依赖库。第三方数据源定义了 Flink 和外部系统数据交互的逻辑,Flink 提供了非常丰富的数据源连接器,例如 Kafka、Elasticsearch、RabbitMQ、JDBC 等。 …...

第四届机电一体化、自动化与智能控制国际学术会议(MAIC 2024)

目录 大会官网 会议简介 组织机构 大会主席 程序委员会主席 主讲嘉宾 征稿主题 参会说明 大会官网 http://www.icmaic.org 会议简介 第四届机电一体化、自动化与智能控制国际学术会议&#xff08;MAIC 2024&#xff09;将于2024年9月27-29日在中国成都召开。MAIC 20…...

leetcode 089 打家劫舍

leetcode 089 打家劫舍 题目 一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响小偷偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警。 给定…...

等保测评基础知识(六)

《计算机病毒防治管理办法》51号令 第十四条 从事计算机设备或者媒体生产、销售、出租、维修行业的单位和个人,应当对计算机设备或者媒体进行计算机病毒检测、清除工作,并备有检测、清除的记录。 第十九条 计算机信息系统的使用单位有下列行为之一的,由公安机关处以警告…...

作业帮 TiDB 7.5.x 使用经验

作者&#xff1a; 是我的海 原文来源&#xff1a; https://tidb.net/blog/5f9784d3 近期在使用 TiDB 时遇到的一些小问题的梳理总结&#xff0c;大部分版本都在6.5.6和7.5.2 1、limit 导致的扫描量过大的优化 研发定时任务每天需要扫描大量数据&#xff0c;到时机器网卡被…...

c语言练习题1

1.输出Helloword /*输出Helloword*/ #include<stdio.h> int main() {printf("Hello word!");return 0; }2.整型变量的定义与使用 /*整型变量的定义与使用*/ #include <stdio.h> int main() {int a;int b;a 10;b 20;int c a b;int d a - b;printf(…...

嵌入式开发就业方向有哪些?前景未来可期!

在科技日新月异的今天&#xff0c;嵌入式系统几乎渗透到了我们生活的各个角落。从简单的家用电器到复杂的工业自动化设备&#xff0c;再到我们手中的智能手机&#xff0c;无一不体现出嵌入式技术的魅力。因此&#xff0c;嵌入式领域的就业前景广阔&#xff0c;为众多求职者提供…...

系列:水果甜度个人手持设备检测-github等开源库和方案

系列:水果甜度个人手持设备检测 -- github等开源库和方案 概述 通常来说&#xff0c;年纪轻轻的我们一般都喜欢走捷径&#xff0c;对于智能设备和算法软件领域来说&#xff0c;GitHub应该算为数不多的的捷径之一。就算因为效果不好/知识产权/方向不同等原因不用&#xff0c;…...

Visual Studio中 生成版本号

Visual Stuodio WPF项目 自动生成版本号 生成递增版本号 软件版本号主要标识了软件的版本&#xff0c;通过其可以了解软件、类库文件的当前版本&#xff0c;使得软件版本控制有所依据。 我们也可以在项目属性上可以看到相关设置的界面&#xff0c;对应的英文名称分别为&#…...

AI入门指南(四):分类问题、回归问题、监督、半监督、无监督学习是什么?

文章目录 一、前言二、分类问题、回归问题是什么&#xff1f;分类问题概念常见算法分类问题的实际应用&#xff1a;银行贷款审批案例 回归问题概念常见算法回归问题实际应用&#xff1a;线性回归模型预测房价 小结 三、监督、半监督、非监督学习是什么&#xff1f;监督学习非监…...

Linux下本地端口转发

在Linux下进行本地端口转发处理&#xff0c;可以进行如下操作&#xff1a; 1.确认NetFilter相关驱动编译到内核&#xff0c;并且CONFIG_IP_NF_TARGET_REDIRECTy&#xff1b; 2.开启转发功能&#xff1a;echo 1 > /proc/sys/net/ipv4/ip_forward&#xff1b; 3.设置转发规…...

RPC 和 HTTP 理解

网上充斥着各类类似于这样的文章&#xff1a;rpc 比 http 快了多少倍&#xff1f;既然有了 http&#xff0c;为什么还要用 rpc 调用等等。遇到这类文章&#xff0c;说明对 http 和 rpc 是由理解误区的。 这里再次重复强调一遍&#xff0c;通信协议不是 rpc 最重要的部分&#x…...

Visual Studio 2022 v17.11 发布

Visual Studio 2022 版本 17.11 正式发布 (GA)&#xff0c;此版本主要是基于用户反馈的各项改进。 “每项增强、每项修复和每项新功能均根据你的反馈而制定。无论你是在构建 Web、桌面、云还是游戏应用程序&#xff0c;Visual Studio 2022 v17.11 都旨在让你的开发体验更流畅、…...

通讯专题-RS232

1 概述 RS-232是一种点对点通信协议&#xff0c;这意味着每个数据信号沿一根导线传输&#xff08;差分信号使用两根导线传输一个数据信号&#xff09;&#xff0c;RS-232为全双工方式运行&#xff08;总线可同时发送和接收数据&#xff09;。 根据新修订的标准为容性负载为2500…...

桥接模式详解

桥接模式 概念: 将抽象部分和实现部分分离, 使他们都可以独立的变化 概念很抽象, 难以理解, 我们举个例子 例子 设想三种不同品牌的汽车 大车 中车 小车 三种不同类型的引擎 纯电引擎 混动引擎 燃油引擎 如果我们把他们两两组合, 都继承同一个类的话,就会有9个类, 并且如果后…...

使用一致性哈希解决哈希分片负载均衡的扩展性问题

声明&#xff1a;本文的图全部源于&#xff1a;小林coding 上来咱先说&#xff0c;一致性哈希是应对分布式系统的算法 假设有一个负载均衡问题&#xff0c;也就是大批流量来请求&#xff0c;那怎么分配这些流量&#xff1f; 随机&#xff1f;还是挨个轮询&#xff1f; 这都…...

探索 Resolume Arena 7 - 引领 VJ 音视频创作的卓越软件

Resolume Arena 7 是一款专为 Mac 和 Windows 系统设计的强大 VJ 音视频软件&#xff0c;为创意专业人士和爱好者提供了丰富而出色的功能。 这款软件拥有直观且用户友好的界面&#xff0c;即使对于初学者来说&#xff0c;也能快速上手并开始创作。其强大的媒体管理功能&#x…...

三勾点餐系统|支持多端发布,方便二次开发

版本号1.7更新日志 新增&#xff1a;腾讯地图key设置&#xff08;更新后请设置key&#xff09; 新增&#xff1a;支付宝小程序登录和支付 新增&#xff1a;前端点餐时选择门店 新增&#xff1a;前端点餐页面优惠活动显示 新增&#xff1a;H5修改手机号 新增&#xff1a;H…...

深入理解AES加密算法:原理与Python实现

目录 深入理解AES加密算法&#xff1a;原理与Python实现1. AES算法简介2. AES加密解密流程3. Python实现AES加密解密4. 结论 深入理解AES加密算法&#xff1a;原理与Python实现 AES (Advanced Encryption Standard) 是目前最广泛使用的对称加密算法之一。它具有高效、安全和灵…...

Redis中List数据类型常用命令

目录 1. 基本操作 &#xff08;1&#xff09;在列表的头部插入一个元素 &#xff08;2&#xff09;在列表的尾部插入一个元素 &#xff08;3&#xff09;获取列表的长度 &#xff08;4&#xff09;获取列表中的元素 2. 读取和修改 &#xff08;1&#xff09;获取列表的范围&…...

借助Aapose.Cells 使用 C# 在 Excel 中读取、添加和编辑线程注释

Excel 中的线程注释是协作工作的重要功能。它允许多个用户在共享文档中添加、编辑和查看对话线程。在某些情况下&#xff0c;我们可能需要以编程方式管理这些线程注释。在这篇博文中&#xff0c;我们将学习如何使用 C# 在 Excel 中读取、添加和编辑线程注释。 Aspose.Cells 是…...

关于c++ grpc 和 c# grpc 通信的问题 以及 grpc 认证问题

一、c 和 c# 通信 c# 端服务器 如果域名 输入的是 https &#xff0c;则 c 端需要匹配使用&#xff0c;也就是c 端需要进行安全认证。如果是http 则c 端不需要认证&#xff08;基于c#的grpc 未 通信成功&#xff09; 参考如下网址可以写一个简单的 .net grpc服务器 &#xff08…...

C++进阶(14)类型转换、IO流

文章目录 一、类型转换C语言隐式类型转换强制类型转换 C类型转换的情况类型转换的函数&#xff08;4个&#xff09; 二、IO流1、缓冲区2、提高输入输出效率3、文件操作文件权限写操作 --- ofstream文本方式写入二进制方式写入 读操作 --- ifstream文本方式读取二进制方式读取 其…...

配置oss cdn加速静态资源访问 阿里云

效果对比 配置cdn下载速度对比 步骤 1: 登录阿里云控制台控制台主页&#xff0c;找到并点击“对象存储 OSS” 创建存储空间&#xff08;Bucket&#xff09; 设置权限 步骤 2: 获取外网访问地址 步骤 3 在 CDN 中使用该地址 复制该外网访问地址 打开全站加速 DCDN/域名管理 添…...

实现 前端框架 SPA 路由功能:Hash 模式与 History 模式的手动实现

前言 在前端框架&#xff08;如 Vue.js、React 等&#xff09;中&#xff0c;路由管理通常会配置一个 router 对象来定义 URL 路径与组件的映射关系。 路径&#xff08;path&#xff09;: 这是浏览器 URL 的一部分&#xff0c;比如 /home 或 /about。组件&#xff08;compone…...

去中心化的新时代:Web3技术的全球影响

随着技术的不断演进&#xff0c;Web3正引领互联网的去中心化新时代。相较于传统的Web1和Web2&#xff0c;Web3通过去中心化、区块链和智能合约等技术&#xff0c;正在重塑网络的运作方式。这一变革不仅提升了网络的安全性和透明度&#xff0c;也对全球经济、社会和文化产生了深…...

初始redis:List

列表 List 相当于数组或者顺序表。 对于List来说&#xff0c;两侧都可以插入和删除&#xff0c;时间复杂度是O(1)。 有很多的操作&#xff0c;比如 llen 可以获取List的长度&#xff0c;lrem 可以删除元素 &#xff0c;lrange可以去一个字符串 &#xff0c; lindex可以根据下标…...

经典语录网站做合格党员/关键词规划师工具

文章目录 一. 简介 二. 自动提交偏移量 三. 手动提交偏移量 3.1 引入依赖 3.2 Kafka配置 3.2.1 生产者 3.2.2 消费者 3.2.3 测试 源码地址 项目推荐 该篇博客实现Springboot整合kafka ,自动&#xff0c;手动提交偏移量 更多高级用法请看下篇博客 一. 简介 kafka概念相关的介绍…...

江苏建设纸质考试网站/在线培训课程

首先关于生成器的那些事&#xff1a;1.通常的for…in…循环中&#xff0c;in后面是一个数组&#xff0c;这个数组就是一个可迭代对象&#xff0c;类似的还有链表&#xff0c;字符串&#xff0c;文件。它的缺陷是所有数据都在内存中&#xff0c;如果有海量数据的话将会非常耗内存…...

网站续费通知/百度链接提交入口

Matplotlib是Python中的一个库&#xff0c;它是数字的-NumPy库的数学扩展。轴类包含大多数图形元素&#xff1a;Axis&#xff0c;Tick&#xff0c;Line2D&#xff0c;Text&#xff0c;Polygon等&#xff0c;并设置坐标系。 Axes实例通过callbacks属性支持回调。matplotlib.axes…...

如何给一个公司做网站/搜索引擎优化入门

虽然此前已经多次提及&#xff0c;但在这里我要再次强调2015年作为云计算全面崛起元年的重要地位&#xff0c;这在很大程度上是因为这一年内出现了众多值得高度关注的大事件——包括戴尔/EMC的合并&#xff0c;而这些标志性事件意味着新的时代已然来临。这是一种直白而决绝的表…...

宠物食品 中企动力提供网站建设/武汉seo优化公司

邮件服器软件种类繁多&#xff0c;但大都离不开SMTP&#xff08;简单邮件传输协议&#xff09;&#xff0c;本文就从SMTP协议入手讲解如何检测一般性邮件故障。所以这里不必考虑你用的是EXCHANGE还是IMAIL等等。常见可能故障&#xff1a;1.对方邮箱爆满&#xff0c;附件超过对方…...

营销网站建设公司地址/查收录网站

软件工程概述 软件的定义 软件是计算机程序、规程、以及运行计算机系统可能需要的相关文档和数据 或者说 软件是包括程序、数据和文档的完整集合 软件是一种具有抽象的逻辑实体 软件的开发是一种逻辑思维成熟的过程&#xff0c;而无明显的制造过程 软件的分类 按照划分方式的…...