动态规划day35|1049. 最后一块石头的重量 II(等效转换得很巧妙)、494. 目标和(超重要!!背包的本质)、474. 一和零(多维控制)

server/2024/9/19 6:46:45/ 标签: 动态规划, 算法, c++, leetcode, 字符串, stl

动态规划day35|1049. 最后一块石头的重量 II、494. 目标和、一和零

  • 1049. 最后一块石头的重量 II
  • 494. 目标和
  • 474. 一和零

1049. 最后一块石头的重量 II

有一堆石头,用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。

每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为 xy,且 x <= y。那么粉碎的可能结果如下:

  • 如果 x == y,那么两块石头都会被完全粉碎;
  • 如果 x != y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x

最后,最多只会剩下一块 石头。返回此石头 最小的可能重量 。如果没有石头剩下,就返回 0

示例 1:

输入:stones = [2,7,4,1,8,1]
输出:1
解释:
组合 2 和 4,得到 2,所以数组转化为 [2,7,1,8,1],
组合 7 和 8,得到 1,所以数组转化为 [2,1,1,1],
组合 2 和 1,得到 1,所以数组转化为 [1,1,1],
组合 1 和 1,得到 0,所以数组转化为 [1],这就是最优值。

示例 2:

输入:stones = [31,26,33,21,40]
输出:5

提示:

  • 1 <= stones.length <= 30
  • 1 <= stones[i] <= 100
class Solution {
public:int lastStoneWeightII(vector<int>& stones) {int sum=0;for(int i=0;i<stones.size();i++)sum+=stones[i];int target=sum/2;vector<int> dp(1501,0);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]*2;}
};

本题的思路即等效转换是最难的,里面使用背包的过程反而不难,只要注意一下dp数组初始化的大小就行了

等效转换思路:本题属于优化类问题,我们可以联想到01背包。我们把整个集合平分成2份,保证2份的各自的元素和几乎相等或者说是和最为接近的两个子集。这样这两个子集一旦相减,最后的结果也就等效于最后一个石头的最小重量了。

494. 目标和

给你一个非负整数数组 nums 和一个整数 target

向数组中的每个整数前添加 '+''-' ,然后串联起所有整数,可以构造一个 表达式

  • 例如,nums = [2, 1] ,可以在 2 之前添加 '+' ,在 1 之前添加 '-' ,然后串联起来得到表达式 "+2-1"

返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目。

示例 1:

输入:nums = [1,1,1,1,1], target = 3
输出:5
解释:一共有 5 种方法让最终目标和为 3 。
-1 + 1 + 1 + 1 + 1 = 3
+1 - 1 + 1 + 1 + 1 = 3
+1 + 1 - 1 + 1 + 1 = 3
+1 + 1 + 1 - 1 + 1 = 3
+1 + 1 + 1 + 1 - 1 = 3

示例 2:

输入:nums = [1], target = 1
输出:1

提示:

  • 1 <= nums.length <= 20
  • 0 <= nums[i] <= 1000
  • 0 <= sum(nums[i]) <= 1000
  • -1000 <= target <= 1000
class Solution {
public:int findTargetSumWays(vector<int>& nums, int target) {int sum=0;for(int i=0;i<nums.size();i++)sum+=nums[i];if((sum+target)%2==1)return 0;if(abs(target)>sum)return 0;int bagSize=(sum+target)/2;vector<vector<int>> dp(nums.size(),vector<int>(bagSize+1,0));dp[0][0]=1;if(bagSize>=nums[0])dp[0][nums[0]]=1;int zeroNum=0;for(int i=0;i<nums.size();i++){if(nums[i]==0)zeroNum++;dp[i][0]=(int)pow(2.0,zeroNum);}for(int i=1;i<nums.size();i++)for(int j=1;j<=bagSize;j++)if(j<nums[i]) dp[i][j]=dp[i-1][j];elsedp[i][j]=dp[i-1][j]+dp[i-1][j-nums[i]];return dp[nums.size()-1][bagSize];}
};

使用二维背包,更容易理解一些

难点:

  • 等效转换:将原集合分成两个子集,代表一正一负,二者相加是sum,相减是target,由此可得出正子集的和为(sum+target)/2。所以将问题转化为:在原来的集合中找,使得他们相加为(sum+target)/2,问这有多少种情况。这样的话我们就可以用01背包了:背包容量为(sum+target)/2,在这群物品里面任意挑,装满背包的方法有多少种?
  • 和最大价值和问题的比较:这种背包思路和以往的不一样,不讨论物品的价值。之前是不求装满,但求价值和最大;而这里是必须要装满背包,然后求出有多少种装满的方法。最大价值和的问题里面可能出现重量小但是价值大或者重量大但是价值小的情况,所以在决定放不放的时候我们需要进行比较(即max方法),每次都是得出最优的dp [i] [j],然后动态规划下去;而这里求的是装满背包的方法数问题,问题来了,既然dp数组的含义都不一样,那我们为什么可以套用01背包的框架呢?这就是涉及到背包的本质了。
  • 背包的本质:背包问题,本质上就是在一个数组内求特定和问题。只要我们需要在一个数组内求特定和,那么这个特定和就是背包容量,背包内的元素都是在这个数组里面找的。只要满足这个情境,就可以套用01背包的框架!但是不是死板的,需要灵活理解。而且这个仅仅是解决问题的基础,还要根据不同题目做出变化
  • 尽管都是背包,但dp数组的意义是不断变化的。意义不同,递推公式就不同。但是任然保留了主体框架不变。这里的求方法数,肯定是需要加在一起的,而不是去最大值:dp [i] [j]=dp [i-1] [j]+dp[i-1] [j-nums[i]];

易错点:

  • 剪枝:
if((sum+target)%2==1)return 0;if(abs(target)>sum)return 0;

当这个和不是整数或者大于sum时都不行

  • 横向初始化:dp [0] [0]=1; 只有当容量恰好等于nums[i]时,即dp [0] [nums[0]]=1;(此时最大容量>=nums[0]),其他都为0

  • 竖向初始化:即dp [i] [0],显然为1。但是,当nums[i]为0时,我们就需要另外考虑了,即:

for(int i=0;i<nums.size();i++){if(nums[i]==0)zeroNum++;dp[i][0]=(int)pow(2.0,zeroNum);}

有几个0,那么就有2的几次方个方法

  • 返回值;我们要知道dp数组的含义:装满背包的方法数,所以只要输入我们要求的背包容量、物品数,然后直接返回dp即可,即:
  return dp[nums.size()-1][bagSize];

474. 一和零

给你一个二进制字符串数组 strs 和两个整数 mn

请你找出并返回 strs 的最大子集的长度,该子集中 最多m0n1

如果 x 的所有元素也是 y 的元素,集合 x 是集合 y子集

示例 1:

输入:strs = [“10”, “0001”, “111001”, “1”, “0”], m = 5, n = 3
输出:4
解释:最多有 5 个 0 和 3 个 1 的最大子集是 {“10”,“0001”,“1”,“0”} ,因此答案是 4 。
其他满足题意但较小的子集包括 {“0001”,“1”} 和 {“10”,“1”,“0”} 。{“111001”} 不满足题意,因为它含 4 个 1 ,大于 n 的值 3 。

示例 2:

输入:strs = [“10”, “0”, “1”], m = 1, n = 1
输出:2
解释:最大的子集是 {“0”, “1”} ,所以答案是 2 。

提示:

  • 1 <= strs.length <= 600
  • 1 <= strs[i].length <= 100
  • strs[i] 仅由 '0''1' 组成
  • 1 <= m, n <= 100
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];}
};

虽然是二维数组,本质上还是一维背包,只不过背包有两个维度的控制。需要注意的是,dp数组的含义是背包内元素的个数。


http://www.ppmy.cn/server/118978.html

相关文章

python的基础语法

Python 的基础语法非常简洁明了&#xff0c;适合初学者快速上手。下面我将为你总结几个最重要的基础语法点&#xff0c;帮你快速掌握 Python 的核心概念。让我们从基础开始逐步深入&#xff0c;像刷副本一样一关一关地攻克它们&#xff01; 1. Hello, World! 每一种编程语言的…

spug项目实现代码本地启动步骤

一、spug代码仓库地址: spug: 开源运维平台&#xff1a;面向中小型企业设计的无 Agent的自动化运维平台&#xff0c;整合了主机管理、主机批量执行、主机在线终端、文件在线上传下载、应用发布、任务计划、配置中心、监控、报警等一系列功能。 - Gitee.com 注意&#xff1a;如…

鹰眼降尘系统多少钱

关于鹰眼系统的价格&#xff0c;由于该系统可能涉及多个领域和不同的配置&#xff0c;因此价格范围可能相对较广。以下是朗观视觉小编对鹰眼系统价格的一些分析和说明&#xff1a; 一、价格影响因素 应用领域&#xff1a;鹰眼系统可能应用于不同的领域&#xff0c;如环保降尘、…

Linux中权限和指令

&#x1f4a5;1、Linux基本指令 1.1 mv 指令 mv指令是move的缩写&#xff0c;用来移动或重命名文件、目录&#xff0c;经常用来备份文件或目录。 mv old_name new_name&#xff1a; 重命名文件或目录mv file /path/to/directory&#xff1a; 移动文件到指定目录 roothcss-ecs…

Unity URP APK打包物体不渲染问题

在测试Shader性能的时候&#xff0c;打包到真机上测试是不可少的。但在一次打包APK时安装&#xff0c;打开程序竟然发现本应该生成的物体都不渲染了&#xff0c;但是在Debug的输出UI上确确实实生成了固定数量的物体&#xff0c;而它们的MeshRender却没有任何渲染&#xff0c;但…

安装2024最新版Android Studio 最详细教程(带图展示)

一、安装JDK &#xff08;1&#xff09;首先在除C盘以外的盘建立文件夹&#xff0c;分别保存软件位置&#xff0c;JDK位置与SDK位置&#xff0c; 特别注意&#xff1a;所有文件名中不要出现空格&#xff0c;而且每个文件夹都是为空的状态 这里我是在D盘中操作。 &#xff0…

Spring Boot 项目的 pom.xml 中,groupId、artifactId 等信息要如何定义?——定义规则及案例

文章目录 1. groupId2. artifactId3. version1. 快照版本&#xff08;Snapshot Version&#xff09;2. 最终发布版本&#xff08;Release Version&#xff09;如何设置版本快照版本与发布版本的区别总结什么时候使用 4. name 和 description示例 pom.xml 配置&#xff1a;小结 …

828华为云征文|Flexus云服务器X实例部署宝塔运维面板

本次华为云Flexus云服务器X实例部署宝塔运维面板教学&#xff0c;这次是推陈出新啊 之前的云耀云服务器L实例已经很不错了&#xff0c;大力赞叹华为云的 同时感谢华为云提供优惠卷&#xff0c;只能说白嫖真是太棒了 华为云近期正在筹办华为云828企业节活动&#xff0c;90款免…

IMS中的号码规整 5G注册流程中的语音相关参数

目录 1. IMS中的号码规整 1.1 主要内容 1.2 什么是 IMS 的号码规整及 FAQ 1.3 VoNR(VoLTE) 打 VoNR(VoLTE),被叫号码规整流程 主叫 AS 来做规整 主叫 S-CSCF 来做规整 2. 5G注册流程中的语音相关参数 2.1 主要内容 2.2 使用 VoNR 的第一步:5G注册流程 2.3 5G 注册流…

如何用python做一个计算器

很久不更新了&#xff0c;今天来更新一下&#xff0c;初学python&#xff0c;若有可以完善部分可以私信&#xff0c;谢谢大家的支持&#xff0c;代码如下&#xff1a; print("欢迎使用计算器")aint(input("请输入第一个数字\n")) bint(input("请输入第…

【rust】rust条件编译

在c语言中&#xff0c;条件编译是一个非常好用的功能&#xff0c;那么rust中如何实现条件编译呢? rust的条件编译需要两个部分&#xff0c;一个是fratures&#xff0c;另一个是cfg。Cargo feature是一个非常强大的功能&#xff0c;可以提供条件编译和可选依赖项的高级特性&…

白月光git

感觉bug好多干脆直接从头到脚梳理 感冒不嘻嘻 近况是&#xff1a; 早起学习 开车去沟里 把蜜蜂拍到狗身上 把车开回来 吃席 安装git和VScode 都是从官网上装的&#xff0c;不说那么多咯&#xff0c;之前说过&#xff1a; 进程间也要唠一唠-CSDN博客https://blog.csdn.net…

RGB颜色传感器简介

RGB颜色传感器是一种能够检测物体颜色并将其转换为电信号输出的电子设备&#xff0c;主要用于识别和测量物体的颜色信息。其工作原理、特点和应用领域如下&#xff1a; 1. 工作原理&#xff1a; 三原色感应&#xff1a;RGB颜色传感器对红(Red)、绿(Green)、蓝(Blue)三种基本颜…

Xilinx系FPGA学习笔记(九)DDR3学习

系列文章目录 文章目录 系列文章目录前言DDR介绍DDR的IP核学习接口信号解析读写流程分析AXI 前言 这里暂时先只介绍一下IP核配置生成和一些接口信号的含义&#xff0c;后续还需要补很多知识点和实际测试应用 DDR介绍 DDR3 已不是当今主流的 DDR 存储器&#xff0c;市场上的 …

visual prompt tuning和visual instruction tuning

visual prompt tuning&#xff1a;作为一种微调手段&#xff0c;其目的是节省参数量&#xff0c;训练时需要优化的参数量小。 输入&#xff1a;视觉信息image token可学习的prompt token 处理任务&#xff1a;比如常见的分类任务 visual prompt tuning visual instruction tu…

vim的 配置文件

vim 的配置文件名是vimrc&#xff0c;共有两个&#xff0c;一个是公共的、所有用户的vimrc&#xff0c;一个是私有的、个人的.vimrc。个人的配置文件是隐藏的&#xff0c;不进行配置的话一般是没有这个文件的&#xff0c;需要自己创建.vimrc 公共配置文件位于 :/etc/vim/vimrc…

CS61C 2020计算机组成原理Lecture03

1、C Operators Operator Precedence 2、Arrays 1、Pointing to Different Size Objects 2、sizeof&#xff08;&#xff09; 3、 Struct Alignment 四字节边界&#xff1a;指的是内存地址能够被4整除的情况。在计算机内存中&#xff0c;每个存储位置都有一个唯一的地址。当…

RedisTemplate混用带来的序列化问题

最近在工作中发现一个现象&#xff0c;项目中使用了不同的 RedisTemplate 来操作redis&#xff0c;有的同事用默认的 RedisTemplate &#xff0c;有的同事用 StringRedisTemplate。这就导致了我本次遇到的问题&#xff1a; 在一次需求中&#xff0c;我需要从 redis 中取值&…

开思通智网-科技快报20240912:人工智能辅助实现复杂糖苷分子检测

【本周新进展】 人工智能辅助实现复杂糖苷分子检测 https://news.sciencenet.cn/htmlnews/2024/9/529548.shtm IFA2024|元鼎智能推出全新“真智能”泳池机器人 https://tech.gmw.cn/2024-09/07/content_37548570.htm 马斯克宣称的“最强AI训练系统”上线 https://news.science…

nginx进阶篇(二)

文章目录 概图一、 Nginx服务器基础配置实例二、Nginx服务操作的问题三、Nginx配置成系统服务四、Nginx命令配置到系统环境五、Nginx静态资源部署5.1 Nginx静态资源概述5.2 Nginx静态资源的配置指令5.2.1. listen指令5.2.2. server_name指令配置方式匹配执行顺序 5.2.3 locatio…