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

最后一块石头的重量II

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

每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 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

本题与分割等和子集很像。

使用滚动数组,dp[j]表示容量为j的背包所具有的价值(j容量的石头价值也是j)

初始化均为0.

 递推公式 要么没使用i位置的石头 就是dp[j];要么使用i位置的石头 就是dp[j-stone[i]]+stone[i]。

顺序,由于使用的是滚动数组,那我们就先遍历物品,再遍历容量,且容量遍历是从后往前遍历。

最后的输出,我们得到了 dp[target], sum- dp[target]就是另一半的值,做差就可得到结果。

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

目标和

给你一个非负整数数组 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

假设加法的总和为x,那么减法对应的总和就是sum - x。

所以我们要求的是 x - (sum - x) = target

x = (target + sum) / 2

此时问题就转化为,用nums装满容量为x的背包,有几种方法

(C++代码中,输入的S 就是题目描述的 target)
if ((target + sum) % 2 == 1) return 0; // 此时没有方案

同时如果target 的绝对值已经大于sum,那么也是没有方案的。

if (abs(target) > sum) return 0; // 此时没有方案
确定dp数组以及下标的含义

先用 二维 dp数组求解本题,dp[i][j]:使用 下标为[0, i]的nums[i]能够凑满j(包括j)这么大容量的包,有dp[i][j]种方法。

递推公式

抽象化如下:

  • 不放物品i:即背包容量为j,里面不放物品i,装满有dp[i - 1][j]中方法。

  • 放物品i: 即:先空出物品i的容量,背包容量为(j - 物品i容量),放满背包有 dp[i - 1][j - 物品i容量] 种方法。

if(nums[i]>j) dp[i][j] = dp[i-1][j];
else dp[i][j] = dp[i-1][j] + dp[i-1][j-nums[i]]; 

初始化 

最上方 把nums[0]=j 的dp[0][j]位置的dp初始化为1.

至于最左侧的初始化,要考虑nums数组中有多少个0,如果没有0,初始化为1;如果有n个0,初始化为2的n次方。

遍历顺序任意。

class Solution {
public:int findTargetSumWays(vector<int>& nums, int target) {int sum = 0;for(int num:nums){sum += num;}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));for(int i = 0;i<nums.size();i++){dp[i][0] = 1;}for(int j = 0;j<=bagSize;j++){if(j==nums[0]){dp[0][j] = 1;}}int numZero = 0;for (int i = 0; i < nums.size(); i++) {if (nums[i] == 0) numZero++;dp[i][0] = (int) pow(2.0, numZero);}for(int i = 1;i<nums.size();i++){for(int j = 1;j<=bagSize;j++){if(nums[i]>j) dp[i][j] = dp[i-1][j];else dp[i][j] = dp[i-1][j] + dp[i-1][j-nums[i]]; }}return dp[nums.size()-1][bagSize];}
};

 


一和零

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

请你找出并返回 strs 的最大子集的长度,该子集中 最多 有 m 个 0 和 n 个 1 。

如果 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

确定dp数组(dp table)以及下标的含义

dp[i][j]:最多有i个0和j个1的strs的最大子集的大小为dp[i][j]

确定递推公式:

dp[i][j] 可以由前一个strs里的字符串推导出来,strs里的字符串有zeroNum个0,oneNum个1。

dp[i][j] 就可以是 dp[i - zeroNum][j - oneNum] + 1。

然后我们在遍历的过程中,取dp[i][j]的最大值。

所以递推公式:dp[i][j] = max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);

 顺序均由后向前。

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 oneNum = 0;int zeroNum = 0;for(char c:str){if(c=='0') zeroNum++;else oneNum++;}for(int i = m;i>=zeroNum;i--){for(int j = n;j>=oneNum;j--){dp[i][j] = max(dp[i][j],dp[i-zeroNum][j-oneNum]+1);}}}return dp[m][n];}
};

 

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

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

相关文章

Java内存模型(Java Memory Model,JMM)

​​ JMM​​ 是Java虚拟机&#xff08;JVM&#xff09;规范中定义的一组规则和规范&#xff0c;用于描述多线程环境下&#xff0c;Java程序中变量的访问和修改行为&#xff0c;尤其是在并发编程中如何保证内存可见性、原子性和有序性。JMM 是 Java 并发编程的基石&…

【swoole Windows 开发(swoole-cli 开发 hyperf)】

先前swoole在Windows平台的开发体验极差&#xff0c;如果在Windows开发swoole的东西可以用docker或者虚拟机&#xff0c;远程开发&#xff0c;体验比较好的是直接Mac或者Linux系统开发。但是作为window平台的钉子户表示我穷。swoole之前已经推出了cygwin64编译成winwods版本的方…

兴达餐饮 酒店 进销存管理系统软件

兴达餐饮 酒店 进销存管理系统软件

Seal Report:一款免费开源的报表工具

Seal Report 是一款基于 C# 语言开发的开源报表工具&#xff0c;可以从各种数据库或 NoSQL 数据源中生成日常报告&#xff0c;并且执行复杂的计划任务。 功能特性 免费开源&#xff1a;源代码托管在 GitHub 上&#xff0c;用户可以自由使用、修改、甚至集成到自己的系统中&…

WebRTC 多媒体 SDP 示例与解析

webRTC中的SDP的Bundlle可能包含一个或者多个媒体块&#xff08;媒体描述, 源码对应类ContentInfo&#xff09;&#xff0c;从 m 开始到下一个 m 行&#xff08;或 SDP 结束&#xff09;之间的所有属性&#xff08;包括 a&#xff09;都属于同一个媒体块&#xff08;media sect…

SpringBoot 启动富文本文字更改

正常来说 SpringBoot启动时候&#xff0c;展示的文字是这个 、 主播这边想要换一个样式&#xff0c;换一个自己自定义的文字 这边换成了自己的博客名字 具体实现操作如下 在项目目录 resources下创建一个名字为banner.txt的文本&#xff0c;这是SpringBoot启动的时候寻找的…

基于结构熵权-云模型的铸铁浴缸生产工艺安全评价

一、评价模型核心思想 结构熵权法 解决传统熵权法忽略指标间结构关系的问题,通过指标层次网络计算权重。 步骤: 构建工艺安全评价指标体系(树状/网络结构) 计算同级指标间的影响度矩阵 引入修正熵权:wj=1−Ej∑(1−Ek)结构影响因子w_j = \frac{1 - E_j}{\sum (1 - E_k)} \…

[Linux]从零开始的vs code交叉调试arm Linux程序教程

一、前言 最近的项目中需要集成rknn的视觉识别&#xff0c;在这之前我并且没有将rknn集成到自己项目的经验。这里我需要在rknn原本demo的基础上我还需要集成自己的业务代码。但是又有一个问题&#xff0c;原本rknn我们都是使用交叉编译编译到开发板上的&#xff0c;并且我们还要…

视频号私信自动化回复插件

给自己的浏览器插件又增加了视频号斯信的自动化回复搜索&#xff1a;程序员老狼主体逻辑就是&#xff0c;不停的点击打招呼和斯信那个tab切换查看有无小红点&#xff0c;有小红点的会话&#xff0c;就点击。查看有无打招呼&#xff0c;有打招呼就点击&#xff0c;抓取昵称和内容…

Web前端实现银河粒子流动特效的3种技术方案对比与实践

文章目录 前端实现银河粒子流动特效的技术原理与实践 引言:银河粒子特效的技术背景与现状 技术发展历史 当前技术现状 技术原理与实现方案 思维导图:银河粒子特效技术架构 1. CSS3实现方案 基础实现代码 性能优化技巧 2. Canvas 2D实现方案 基础实现代码 Canvas高级优化技术 …

Linux:告别Jammy,拥抱Noble!WSL Ubuntu 22.04 到 24.04 LTS 终极升级指南

大家好&#xff01;如果大家和我一样&#xff0c;是Windows Subsystem for Linux (WSL) 的忠实用户&#xff0c;那么大家一定对Ubuntu在其中的表现印象深刻。我们中的许多人可能还在使用稳定可靠的Ubuntu 22.04 LTS (Jammy Jellyfish)。但现在&#xff0c;一个更令人兴奋的时代…

江协科技STM32 11-1 SPI通信协议

本节课我们将继续学习下一个通信协议&#xff0c;SPI。SPI通信和我们刚刚学习过的I2C通信差不多。两个协议的设计目的都一样都是实现主控芯片和各种外挂芯片之间的数据交流&#xff0c;有了数据交流的能力&#xff0c;我们的主控芯片就可以挂载并操纵各式各样的外部芯片&#x…

预过滤环境光贴图制作教程:第一步 - HDR 转立方体贴图

在基于物理的渲染(PBR)中,环境光贴图是实现真实光照效果的核心组件之一。而将 HDR 全景图转换为立方体贴图,是制作预过滤环境光贴图的基础步骤。本教程将详细讲解如何实现这一转换过程。 什么是 HDR 转立方体贴图? HDR(高动态范围)全景图通常以等矩形投影(Equirectan…

02 深度学习介绍【动手学深度学习v2】| 学习笔记

1、intro自然语言处理虽然我们过去取得了很大的进展&#xff0c;但是实际上还是停留在感知层面。计算机视觉领域&#xff0c;因为图片里面都是像素&#xff0c;像素很难用符号学来解释&#xff0c;所以计算机视觉大部分是用概率模型或机器学习来做。深度学习它是机器学习的一种…

智能学号抽取系统V5.6.4重磅发布

告别随机数&#xff0c;拥抱智能点名&#xff01;—— 全新升级的“智能学号抽取系统V5.6.4”重磅发布&#xff01; 摘要&#xff1a; 还在为课堂随机提问、活动抽奖而手动翻名单、查表格而烦恼吗&#xff1f;还在忍受传统点名工具的简陋和不智能吗&#xff1f;今天&#xff0…

Leetcode-141.环形链表

dict和set 1. 结构上的区别&#xff1a;类型键&#xff08;Key&#xff09;值&#xff08;Value&#xff09;示例dict有有{a: 1, b: 2}set有没有{a, b} dict 是**键值对&#xff08;key-value&#xff09;**的集合。set 是只有键&#xff08;key&#xff09;没有值的一组唯一元…

调节步进电机速度时调PSC和调ARR的区别

在步进电机控制中&#xff0c;调节速度通常是通过改变脉冲频率实现的。代码中选择调节ARR&#xff08;Auto-Reload Register&#xff09;而非PSC&#xff08;Prescaler&#xff09;的原因如下&#xff1a; 1. ARR 与 PSC 的核心区别 • ARR&#xff08;自动重载寄存器&#xff…

在 AKS 中运行 Azure DevOps 私有代理-1

简介 配置 Azure DevOps 私有代理的传统方法是将其部署在虚拟机 (VM) 上。然而,一个有趣的替代方案是利用 Azure Kubernetes 服务 (AKS) 来实现此目的。 本文将指导您如何使用 Helm Chart 在 AKS 集群中设置 Azure DevOps 私有代理,并提供该过程的分步说明。 在 AKS 中部署…

C# _Json数据

目录 1、添加Json库 2、数据序列化&#xff08;对象转 JSON&#xff09;和反序列化&#xff08;JSON 转对象&#xff09;操作 3、序列化 创建和读取Json数据 创建Json数据 定义一个CreateJson方法 读取 解析 Json数据 定义一个ReadJson方法 4、程序运行结果 在 C# 中&…

JavaScript 原始值与引用值

JavaScript 原始值与引用值 ECMAScript变量可以包含两种不同类型的数据&#xff1a;原始值和引用值。 原始值&#xff08;primitive value&#xff09;就是最简单的数据&#xff0c;引用值&#xff08;reference value&#xff09;则是由多个值构成的对象。 保存原始值的变量是…