【25届秋招备战C++】题型练习-背包问题

【25届秋招备战C++】题型练习-背包问题

  • 0-1背包
    • 416 - 分割等和子集
    • 1049 - 最后一块石头的重量 Ⅱ
    • 494 - 目标和
    • 474- 一和零
  • 完全背包
    • 518- 零钱兑换Ⅱ
    • 377- 组合总数Ⅱ
    • 322- 零钱兑换
    • 279- 完全平方数
  • 参考

0-1背包

416 - 分割等和子集

链接: 分割等和子集
解题思路:给定容量判断是否可以满足固定的价值
分割等和问题,只需要求和取一半作为结果即可,总和为奇直接返回false,此题关键在于背包价值的遍历顺序,代码随想录的解释(每一个元素一定是不可重复放入,所以从大到小遍历)很妙
1.确定dp数组以及下标的含义
dp[j] 表示:j容量能装的最大价值,有dp[j]种方法
2.确定递推公式
dp[j]=max(dp[j],dp[j-nums[i]]+nums[i]) 装满j容量的方法数统一公式
3.dp数组如何初始化
dp[0]=1,非零下标初始为0
4.确定遍历顺序
对于01背包问题一维dp的遍历,nums放在外循环,target在内循环,且内循环倒序

class Solution {
public:bool canPartition(vector<int>& nums) {vector<int> dp(10001,0);int sum=0;for(int i=0;i<nums.size();i++){sum +=nums[i];}if (sum % 2 == 1) return false;sum=sum/2;for(int i=0;i<nums.size();i++){for(int j=sum;j>=nums[i];j--){dp[j]=max(dp[j],dp[j-nums[i]]+nums[i]);}}if(dp[sum]==sum){return true;}return false;}
};

1049 - 最后一块石头的重量 Ⅱ

链接: 最后一块石头的重量 Ⅱ
解题思路:其实就是分割等和的变体,只要找到尽可能平分的背包即可。

class Solution {
public:int lastStoneWeightII(vector<int>& stones) {vector<int> dp(15001, 0);int sum = 0;for (int i = 0; i < stones.size(); i++) sum += stones[i];int target = sum / 2;for (int i = 0; i < stones.size(); i++) { // 遍历物品for (int j = target; j >= stones[i]; j--) { // 遍历背包dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]);}}return sum - dp[target] - dp[target];}
};

494 - 目标和

链接: 目标和
解题思路:总容量固定的方法数
分为两个子集,两包和为target,设其中一包的和为x,则另一包的和为sum-x,且x-(sum-x)=target,即x=(taget+sum)/2,即只需要求解总容量为(target+sum)/2的可能方法数
1.确定dp数组以及下标的含义
dp[j] 表示:装满j容量,有dp[j]种方法
2.确定递推公式
dp[j] += dp[j - nums[j]] 装满j容量的方法数统一公式
3.dp数组如何初始化
dp[0]=1,非零下标初始为0
4.确定遍历顺序
对于01背包问题一维dp的遍历,nums放在外循环,target在内循环,且内循环倒序

class Solution {
public:int findTargetSumWays(vector<int>& nums, int S) {int sum = 0;for (int i = 0; i < nums.size(); i++) sum += nums[i];if (abs(S) > sum) return 0; // 此时没有方案if ((S + sum) % 2 == 1) return 0; // 此时没有方案int bagSize = (S + sum) / 2;vector<int> dp(bagSize + 1, 0);dp[0] = 1;for (int i = 0; i < nums.size(); i++) {for (int j = bagSize; j >= nums[i]; j--) {dp[j] += dp[j - nums[i]];}}return dp[bagSize];}
};

474- 一和零

链接: 一和零
解题思路:满足最多m个0,n个1最多有多少个物品

1.确定dp数组以及下标的含义
dp[i][j] 表示:i个0,j个1,最多装dp[i][j]个物品
2.确定递推公式
dp[i][j]=max(dp[i-x][j-y]+1,dp[i][j]) (每个物品的重量是x个0y个1)
3.dp数组如何初始化
dp[0][0]=0,非零下标初始为0
4.确定遍历顺序
对于01背包问题二维dp的遍历,nums放在外循环,target在内循环,且内循环倒序
先遍历物品再遍历背包

class Solution {
public:int findMaxForm(vector<string>& strs, int m, int n) {vector<vector<int>> dp(m+1,vector<int>(n+1,0));for(string str:strs){int x=0,y=0;for(char c:str){if(c=='0') x++;else y++;}for(int i=m;i>=x;i--){for(int j=n;j>=y;j--){dp[i][j]=max(dp[i][j],dp[i-x][j-y]+1);}}}return dp[m][n];}
};

完全背包

518- 零钱兑换Ⅱ

链接: 零钱兑换Ⅱ
解题思路:思路同目标和,注意初始化dp[0]=1其实是为了迎合递推公式,没有实际意义

1.确定dp数组以及下标的含义
dp[j] 表示:装满j容量,有dp[j]种方法
2.确定递推公式
dp[j] += dp[j - nums[j]] 装满j容量的方法数统一公式
3.dp数组如何初始化
dp[0]=1,非零下标初始为0
4.确定遍历顺序
完全背包正序,先物品再背包不会重复是组合数,先背包再物体有顺序是排列数

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-coins[i]];}}return dp[amount];}
};

377- 组合总数Ⅱ

链接: 组合总数Ⅱ
解题思路:思路同零钱兑换Ⅱ,唯一不同是本题强调顺序注意初始化dp[0]=1其实是为了迎合递推公式,没有实际意义

1.确定dp数组以及下标的含义
dp[j] 表示:装满j容量,有dp[j]种方法
2.确定递推公式
dp[j] += dp[j - nums[j]] 装满j容量的方法数统一公式
C++测试用例有两个数相加超过int的数据,所以需要在if里加上dp[i] < INT_MAX - dp[i - num]。
3.dp数组如何初始化
dp[0]=1,非零下标初始为0
4.确定遍历顺序
完全背包正序,先物品再背包不会重复是组合数,先背包再物体有顺序是排列数

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-coins[i]];}}return dp[amount];}
};

322- 零钱兑换

链接: 零钱兑换
解题思路:思路同零钱兑换Ⅱ,但这里是最小值,则初始化时需要给定INT_MAX,且递推公式也要用min取最小

1.确定dp数组以及下标的含义
dp[j] 表示:装满j容量,最少有dp[j]个物品
2.确定递推公式
dp[j] = min(dp[j - nums[j]]+1,dp[j])
C++测试用例有两个数相加超过int的数据,所以需要在if里加上dp[i] < INT_MAX - dp[i - num]。
3.dp数组如何初始化
dp[0]=1,非零下标初始为0
4.确定遍历顺序
完全背包正序,先物品再背包不会重复是组合数,先背包再物体有顺序是排列数

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];}
};

279- 完全平方数

链接: 完全平方数
解题思路:思路同零钱兑换,但这里是最小值,则初始化时需要给定INT_MAX,且递推公式也要用min取最小

1.确定dp数组以及下标的含义
dp[j] 表示:装满j容量,最少有dp[j]个物品
2.确定递推公式
dp[j] = min(dp[j - nums[j]]+1,dp[j])
C++测试用例有两个数相加超过int的数据,所以需要在if里加上dp[i] < INT_MAX - dp[i - num]。
3.dp数组如何初始化
dp[0]=1,非零下标初始为0
4.确定遍历顺序
完全背包正序,先物品再背包不会重复是组合数,先背包再物体有顺序是排列数

public:int numSquares(int n) {vector<int> dp(n + 1, INT_MAX);dp[0] = 0;for (int i = 0; i <= n; i++) { // 遍历背包for (int j = 1; j * j <= i; j++) { // 遍历物品dp[i] = min(dp[i - j * j] + 1, dp[i]);}}return dp[n];}
};

参考

代码随想录救我狗命!!!!!!!!
链接: 代码随想录

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

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

相关文章

单片机中的几种周期(振动/时钟,状态,机械,指令周期)表示的含义(51为例)

几种周期含义及个人理解描述 参考&#xff1a;短文&#xff0c;参考&#xff0c;百度 个人理解简述&#xff1a;对于几个周期性来说&#xff0c;可以认为是小单位的时间组合成了长时间。就像把一个数据赋值&#xff0c;这个是简单的一个机械周期能完成的动作&#xff0c;但需要…

删除远程的master分支,并创建dev分支,将代码推送到dev分支上

在执行这些操作之前&#xff0c;确保你对远程仓库有足够的权限来删除分支和推送代码。下面的步骤将指导你如何删除远程的master分支&#xff0c;创建一个新的dev分支&#xff0c;并将代码推送到这个新分支上。 1. 删除远程的master分支 首先&#xff0c;使用以下命令删除远程…

C语言例:表达式(a=2,3),a+1的值

题目&#xff1a;设int a; 则表达式(a2,3),a1的值 #include<stdio.h> int main(void) {int a0;int b;int c;b (a2,4);c (a2,3),a1;printf("a1%d\n",a1); //a1 3;printf("a2,4的值为&#xff1a;%d\n",b); //a2,4的值为&…

开源模型应用落地-业务优化篇(八)

一、前言 在之前的学习中&#xff0c;我相信您已经学会了一些优化技巧&#xff0c;比如分布式锁、线程池优化、请求排队、服务实例扩容和消息解耦等等。现在&#xff0c;我要给您介绍最后一篇业务优化的内容了。这个优化方法是通过定时统计问题的请求频率&#xff0c;然后将一些…

【进阶五】Python实现SDVRP(需求拆分)常见求解算法——蚁群算法(ACO)

基于python语言&#xff0c;采用经典遗传算法&#xff08;ACO&#xff09;对 需求拆分车辆路径规划问题&#xff08;SDVRP&#xff09; 进行求解。 目录 往期优质资源1. 适用场景2. 代码调整3. 求解结果4. 代码片段参考 往期优质资源 经过一年多的创作&#xff0c;目前已经成熟…

Go函数全景:从基础到高阶的深度探索

目录 一、Go函数基础1.1 函数定义和声明基础函数结构返回值类型和命名返回值 1.2 参数传递方式值传递引用传递 二、Go特殊函数类型2.1 变参函数定义和使用变参变参的限制 2.2 匿名函数与Lambda表达式何为匿名函数Lambda表达式的使用场景 2.3 延迟调用函数&#xff08;defer&…

Arcgis新建位置分配求解最佳商店位置

背景 借用Arcgis帮助文档中的说明:在本练习中,您将为连锁零售店选择可以获得最大业务量的商店位置。主要目标是要将商店定位在人口集中地区附近,因为这种区域对商店的需求量较大。设立这一目标的前提是假设人们往往更多光顾附近的商店,而对于距离较远的商店则较少光顾。您…

北斗垂莽苍 开闭天门路(三)

北斗垂莽苍 开闭天门路(三&#xff09; 北斗垂莽苍 明河浮太清 曾经&#xff0c;北斗七星是中国古人在漫长的历史长河中寻找方向的重要坐标。如今&#xff0c;“天上建好&#xff0c;地上用好”的北斗&#xff0c;已成为助力经济发展和人民生活更加美好的急先锋。 早在2019年&…

【研发体系】CMMI 3 级和 5 级有什么区别?

以下是CMMI Level 3和CMMI Level 5之间的对比表格: CMMI 级别描述特点可测量性重点类比3&#xff08;已定义&#xff09;组织已建立一套标准流程&#xff0c;并始终执行。- 管理实践&#xff1a;完整的实践集涵盖了实践领域的全部意图。 - 定制&#xff1a;使用组织标准和定制…

禁止ie自动跳转edge

因为微软对ie已经彻底停止维护了&#xff0c;对于没有升级系统的用户来说&#xff0c;会自动更新edge然后将ie给禁止使用。下面方法有效的解决windows10下&#xff0c;禁止ie自动跳转edge。 方法一&#xff1a;对于2023年10月份前的更新可用 打开控制面板&#xff0c;点击网络…

STM32使用常见错误合集(正在更新版)

本文章记录一些学习STM32的一些错误问题 一、编译、烧录类问题 1、烧录不成功&#xff0c;Keil提示RDDI-DAP Error【场景&#xff1a;PWM驱动直流电机】 解决方案&#xff1a;将电机断开再进行烧录&#xff0c;断开后就可以美美烧录不报错啦~ 二、Keil使用问题 1、打开一个…

2 .Gen<I>Cam模块介绍

模块组成&#xff1a;GenApi&#xff0c;SFNC&#xff0c;GenTL&#xff0c;GenDC&#xff0c;GenCP。 首先让我来看下 GenTL (Transport Layer) GenApi( sometimes simply called the GenICam Standard) 传统相机应用程序二次开发&#xff0c;是基于相机厂家提供的sdk。使用…

el-table保留勾选的数据(分页、刷新数据)

1.在el-table中添加行标识 :row-key"val > val.id"&#xff0c;这里最好选择能唯一标识每一行的数据作为key的返回值&#xff0c;否则回选失败 <el-table :row-key"val > val.id" :data"tableList" border style"width: 100%&quo…

c++保存结构体数据为二进制文件与读取

写入 #include <iostream> #include <fstream> #include <string>struct testData {char* _name;int _age;

IBM:《2024年消费者调研:无处不在的人工智能彻底变革零售业》

1月17日&#xff0c;IBM商业价值研究院最近发布了第三份两年一度的消费者调研报告。 这项名为《无处不在的人工智能彻底改变零售业&#xff1a;客户不会等待》的报告&#xff0c;对包含中国在内的全球近20000名消费者进行了调研&#xff0c;相关结果反映了消费者对零售体验的普…

Java中 常见的开源树库介绍

阅读本文之前请参阅------Java中 树的基础知识介绍 在 Java 中&#xff0c;有几种流行的开源树库&#xff0c;它们提供了丰富的树算法和高级操作&#xff0c;可以帮助开发者更高效地处理树相关的问题。以下是几种常见的 Java 树库及其特点和区别&#xff1a; JTree 特点…

使用SpaceDesk实现iPad成为电脑拓展屏(保姆级教程)

使用SpaceDesk实现iPad成为电脑拓展屏 SpaceDesk是一个开源的软件, 所以说对学生和平民用户非常的友好, 连接后的画质也非常不错, 而且具有无线和有线两种连接方式. 接下来就开始教程: 1. 安装SpaceDesk电脑版 首先我们要下载SpaceDesk电脑版安装好: SpaceDesk官网 注意: …

计算机网络 网络层设备的 冲突域和广播域

域是指&#xff0c;表示冲突&#xff0c;或者广播在其中发生并传播的区域。 冲突域&#xff0c;是指连接到同一个物理介质上的所有结点的集合&#xff0c;这些结点之间存在介质争用的现象。 在OSI参考模型中&#xff0c;冲突域被视为第一层的概念&#xff0c;像集线器&#x…

C语言自学笔记15----C 语言 void指针

C 语言 void指针 如果我们声明了int指针&#xff0c;则此int指针不能指向float变量或某种其他类型的变量&#xff0c;即它只能指向int类型的变量。 为了克服这个问题&#xff0c;我们使用了指向void的指针。 指向void的指针表示可以指向任何数据类型的通用指针。 我们可以将任何…

探索数据结构:双向链表的灵活优势

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;数据结构与算法 贝蒂的主页&#xff1a;Betty’s blog 1. 前言 前面我们学习了单链表&#xff0c;它解决了顺序表中插入删除需…