5月20日分割等和子集+最后一块石头的重量Ⅱ

news2024/11/26 5:38:53

416.分割等和子集

给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。

示例 1:

输入:nums = [1,5,11,5]
输出:true
解释:数组可以分割成 [1, 5, 5] 和 [11] 。

示例 2:

输入:nums = [1,2,3,5]
输出:false
解释:数组不能分割成两个元素和相等的子集。

提示:

  • 1 <= nums.length <= 200
  • 1 <= nums[i] <= 100

思路

首先我们先判断如果数组长度小于2,则一定无法将数组分割为两个子集,然后统计数组中元素总和,若总和sum为奇数,则也无法分割为两个子集,因为所有元素均为正整数。然后再来思考整个问题:我们想要把整个数组分为两个子集,并且两个子集的元素和相等,那么我们只要确定整个数组中存在元素和等于sum/2的子集即可,我们可以从数组下标[0,i]开始,判断该段元素能否组成和为[1,sum/2]的子集即可,可以使用动态规划法。

记数组长度为n,sum/2为target,定义一个dp数组dp[n][target+1],初始化为false,dp[i][j]表示数组下标从0到i能否组成总和为j的子集。

首先初始化dp数组,如果j==0,那么不选择元素即可,所以我们记为true,如果i为0,此时只有nums[0]可以选择,所以我们记dp[0][nums[0]]=true.

接着是递推公式,我们对dp数组按行进行遍历,如果j>=nums[i],那么需要考虑元素i选择或者不选择的情况,那么dp[i][j]等于dp[i-1][j]与dp[i-1][j-nums[i]]做或运算的结果,前者表示不选择元素i,后者表示选择元素i。如果j<nums[i],那么一定不会选择元素i,因为放入就会导致总和大于目标值j,所以dp[i][j]=dp[i-1][j].

还有一个要注意的点是,如果数组中有元素大于target,即大于总和的一般,那么一定不能分割为两个等和子集,因为数组只包含正整数。

代码

class Solution {
        public boolean canPartition(int[] nums) {
            int n=nums.length;
            if(n<2){
                return false;
            }
            int sum=0,max=0;
            for(int i:nums){
                sum+=i;
                max=Math.max(max,i);
            }
            if(sum%2==1){
                return false;
            }
            int target=sum/2;
            if(max>target){
                return false;
            }
            boolean[][] dp=new boolean[n][target+1];
            for(int i=0;i<n;i++){
                dp[i][0]=true;
            }
            dp[0][nums[0]]=true;
            for(int i=1;i<n;i++){
                int num=nums[i];
                for(int j=1;j<target+1;j++){
                    if(j>=nums[i]){
                        dp[i][j]=dp[i-1][j]|dp[i-1][j-num];
                    }else {
                        dp[i][j]=dp[i-1][j];
                    }
                }
            }

            return dp[n-1][target];
        }
    }

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

有一堆石头,用整数数组 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

思路

用归纳法证明,无论按照任何顺序粉碎石头,最后一块石头的重量总是可以表示成:

\sum_{i=0}^{n-1}k_{i}*sones_{i},k_{i}\in \{-1,1\}

记石头的总重量为sum,ki=-1的石头的重量之和为neg,其余的为sum-leg,则\sum_{i=0}^{n-1}k_{i}*sones_{i}=(sum-neg)-neg=sum-2*neg

要使最后一块石头尽可能小,则要使neg不超过sum/2的情况下尽可能大,因此本问题可以看作背包容量为sum/2,物品重量和价值均为stonesi的01背包问题。

dp数组和递推公式与上题一样,不同之处是仅需初始化dp[0][0]为真。

在递推结束后,找到所有为真的dp[n][j]中,最大的j即为neg能取到的最大值,带入sum-2*neg即可得到最后一块石头的最小重量。

代码

class Solution {
        public int lastStoneWeightII(int[] stones) {
            int n=stones.length;

            int sum=0;
            for(int i:stones){
                sum+=i;
            }
            int target=sum/2;
            boolean[][] dp=new boolean[n+1][target+1];
            dp[0][0]=true;
            for(int i=0;i<n;i++){
                for(int j=0;j<target+1;j++){
                    if(j>=stones[i]){
                        dp[i+1][j]=dp[i][j]|dp[i][j-stones[i]];
                    }else {
                        dp[i+1][j]=dp[i][j];
                    }
                }
            }
            for(int j=target;;j--){
                if(dp[n][j]){
                    return sum-2*j;
                }
            }
        }
    }

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

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

相关文章

Qt moc系统的黑魔法?

Qt的元对象系统&#xff08;Meta-Object System&#xff09;是Qt框架的核心功能之一&#xff0c;为C语言增加了一些动态特性&#xff0c;借助元对象系统Qt可以实现以下功能 信号与槽机制&#xff08;Signals and Slots&#xff09;运行时类型信息&#xff08;Run-Time Type In…

激光雷达和相机外参标定

1、外参标定标定什么&#xff1f; 标定激光雷达和相机之间的相对位置&#xff0c;变换矩阵T 2、原理 通过激光扫描出来的轮廓和相机识别出来的栅格的轮廓进行PNP匹配。 3、论文

IDEA的妙用

IDEA 安装破解 复制JetbrainsIdesCrack-4.2.jar到安装目录下 修改安装目录下的bin目录的idea64.exe.vmoptions&#xff1a; 最后一行添加&#xff1a;-javaagent:E:\develop\JetBrains\IntelliJ IDEA 2018.3.5\bin\JetbrainsIdesCrack-4.2.jar(注意&#xff1a;使用自己的路…

大模型时代,掌握Event Stream技术提升Web响应速度

大模型时代,每天搜索都可能会用到一种或多种大模型,在大文本输出的时候,页面是一字一字,一段一段的慢慢输出出来的,这背后是如何实现的呢?我们以KIMI为例 先抓个请求 我们发现界面展示是一句话,但是接口返回的时候是一个字一个字的。 普通请求 多了Event Stream的处理 …

OS复习笔记ch5-5

引言 上文我们了解了一些关于信号量机制的一些经典应用&#xff0c;知识点比较繁杂&#xff0c;可能会有点啰嗦&#xff0c;但是对初学者而言还是越详细越好。接下来我们介绍一下管程。 管程 管程是程序设计语言结构&#xff0c;可提供易于控制的同步机制&#xff0c;我们熟…

基于 LlaMA 3 + LangGraph 在windows本地部署大模型 (十一)

基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;十一&#xff09; LlaMA 3 系列博客 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;一&#xff09; 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;二&#xff09; 基于 Lla…

【网络安全】2030年十大新兴网络安全威胁

欧盟网络安全局&#xff08;ENISA&#xff09;已发布了一份全面的清单&#xff0c;列出了预计到2030年将影响数字领域的十大新兴网络安全威胁。 该预测是为期八个月的广泛研究的成果&#xff0c;融合了ENISA前瞻专家小组、CSIRTs网络以及欧盟CyCLONe专家的见解。 这项研究突显…

Wpf 使用 Prism 实战开发Day23

自定义对话框服务 当原有对话框不能满足需求的时候&#xff0c;可以通过自定义对话框来实现特殊的需求 一.自定义对话框主机服务步骤&#xff1a; 1.建立一个IDialogHostService 接口类&#xff0c;继承自 IDialogService 对话框服务类。并且自定义基类的服务方法。 public …

真实案例分享,终端pc直接telnet不到出口路由器。

1、背景信息 我终端pc的网卡地址获取的网关是在核心交换机上&#xff0c;在核心交换机上telnet出口路由器可以实现。 所有终端网段都不能telnet出口路由器&#xff0c;客户希望能用最小的影响方式进行解决。 2、现有配置信息 终端的无线和有线分别在两个网段中&#xff0c;…

案例题(第一版)

案例题目 软件架构设计考点&#xff08;历年必考&#xff09; 软件架构设计通常在每年的第一题&#xff0c;该题必考 必备概念 必备概念即考试必须要默写出来的概念 概念描述软件架构风格是指描述特定软件系统组织方式和惯用模式。组织方式描述了系统的组成构件和这些构件的组…

从“图形可视化”到“图生代码”,低代码平台的新挑战

前言&#xff1a; 低代码平台最大的一个特点就是可视化&#xff0c;将代码采用可视化的方式展示管理。一时间拥有图形化界面的各类系统都挂上了低代码的标签。但更多的代码从业者在使用中却发现&#xff0c;在众多的低代码平台中都是“别人家的代码”其可视化主要是别人家的代…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-23.1,2 讲 I2C驱动

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

SpringBoot+layuimini实现角色权限菜单增删改查(layui扩展组件 dtree)

角色菜单 相关组件方法效果图MySQL代码实现资源菜单树组件实现权限树方法js这里我先主要实现权限树的整体实现方法&#xff0c;如果是直接查看使用的话可以只看这里&#xff01; 后端代码Controlle层代码Service代码及实现类代码Service代码ServiceImpl代码 resourceMapper 代码…

指数分布的理解,推导与应用

指数分布的定义 在浙大版的教材中&#xff0c;指数分布的定义如下&#xff1a; 若连续型的随机变量 X X X的概率密度为&#xff1a; f ( x ) { 1 θ e − x θ , x>0 0 , 其他 f(x) \begin{cases} \frac{1}{\theta} e^{-\frac{x}{\theta}}, & \text{x>0}\\ 0, &a…

Jenkins 构建 Web 项目:构建服务器和部署服务器分离的情况

构建命令 #!/bin/bash node -v pnpm -v pnpm install pnpm build:prod # 将dist打包成dist.zip zip -r dist.zip dist

BLE学习笔记(0.0) —— 基础概念(0)

前言 &#xff08;1&#xff09;本章节主要是对BLE技术进行简单的介绍&#xff0c;熟悉蓝牙技术的发展过程&#xff0c;了解相关术语方便后续的学习。 &#xff08;2&#xff09;为了防止单篇博客太长以至于看不下去&#xff0c;因此我基础概念章节分为两篇来写。 &#xff08;…

创新指南|利用电商产品视频进行渠道营销的最佳策略,不断提升销售额

无论企业的利基市场如何&#xff0c;电商产品视频都已被证明是非常可靠的资产&#xff0c;可以让目标受众了解您所提供的产品——关键功能、展示重要的差异化优势甚至改变大多数营销活动的游戏规则。阅读本文&#xff0c;全面了解电商产品视频如何融入营销推广&#xff0c;以最…

IDEA 自定义注解(类注释、方法注释)

一、生成类注释 1、打开设置位置 打开File —> Settings —> Editor —> File and Code Templates —> Files —> Class 2、将自定义的类注解规则&#xff0c;复制到Class中。 /** * * 功能: * * 作者: 暗自着迷 * * 日期: ${YEAR}-${MONTH}-${DAY} ${HOU…

AI图片过拟合如何处理?答案就在其中!

遇到难题不要怕&#xff01;厚德提问大佬答&#xff01; 厚德提问大佬答8 你是否对AI绘画感兴趣却无从下手&#xff1f;是否有很多疑问却苦于没有大佬解答带你飞&#xff1f;从此刻开始这些问题都将迎刃而解&#xff01;你感兴趣的话题&#xff0c;厚德云替你问&#xff0c;你解…

头歌openGauss-存储过程第2关:修改存储过程

任务描述 本关任务&#xff1a; 修改存储过程pro0101&#xff0c;并调用&#xff1b; --修改sel_course表中成绩<60的记录为成绩10&#xff0c;然后将计算机学院所有学生的选课成绩输出&#xff1b; --a、需要先删除存储过程pro0101&#xff1b; drop procedure if exists p…