动态规划:11分割等和子集

news2025/7/10 17:04:01

动态规划:11分割等和子集

在这里插入图片描述

416. 分割等和子集

这道题目初步看,和如下两题几乎是一样的,大家可以用回溯法,解决如下两题

  • 698.划分为k个相等的子集
  • 473.火柴拼正方形

这道题目是要找是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。

那么只要找到集合里能够出现 sum / 2 的子集总和,就算是可以分割成两个相同元素和子集了。

本题是可以用回溯暴力搜索出所有答案的,但最后超时了,也不想再优化了,放弃回溯,直接上01背包吧。

如果对01背包不够了解,建议仔细看完如下两篇:

  • 动态规划:09 0-1背包理论基础I
  • 动态规划:10 0-1背包理论基础II(滚动数组)

01背包

背包问题,大家都知道,有N件物品和一个最多能背重量为W 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。

背包问题有多种背包方式,常见的有:01背包、完全背包、多重背包、分组背包和混合背包等等。

要注意题目描述中商品是不是可以重复放入。

即一个商品如果可以重复多次放入是完全背包,而只能放入一次是01背包,写法还是不一样的。

要明确本题中我们要使用的是01背包,因为元素我们只能用一次。

回归主题:首先,本题要求集合里能否出现总和为 sum / 2 的子集。

那么来一一对应一下本题,看看背包问题如何来解决。

只有确定了如下四点,才能把01背包问题套到本题上来。

  • 背包的体积为sum / 2
  • 背包要放入的商品(集合里的元素)重量为 元素的数值,价值也为元素的数值
  • 背包如果正好装满,说明找到了总和为 sum / 2 的子集。
  • 背包中每一个元素是不可重复放入。

以上分析完,我们就可以套用01背包,来解决这个问题了。

五部曲

  1. 确定dp数组含义:dp[j] 表示: 容量为j的背包,所背的物品价值最大可以为dp[j]。

    本题中每一个元素的数值既是重量,也是价值。

    套到本题,dp[j]表示 背包总容量(所能装的总重量)是j,放进物品后,背的最大重量为dp[j]

    那么如果背包容量为target, dp[target]就是装满 背包之后的重量,所以 当 dp[target] == target 的时候,背包就装满了。

    大家可能想,那还有装不满的时候?

    拿输入数组 [1, 5, 11, 5],举例, dp[7] 只能等于 6,因为 只能放进 1 和 5。

    而dp[6] 就可以等于6了,放进1 和 5,那么dp[6] == 6,说明背包装满了。

    我们只需要判断dp[j]的最大值是否等于j,就可以判断是否装满

  2. 确定递归公式:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

    本题,相当于背包里放入数值,那么物品i的重量是nums[i],其价值也是nums[i]。

    所以递推公式:dp[j] = Math.max(dp[j], dp[j - nums[i]] + nums[i]);

  3. dp数组初始化:dp[j] = 0

    在01背包,一维dp如何初始化,已经讲过,

    从dp[j]的定义来看,首先dp[0]一定是0。

    如果题目给的价值都是正整数那么非0下标都初始化为0就可以了,如果题目给的价值有负数,那么非0下标就要初始化为负无穷。

    这样才能让dp数组在递推的过程中取得最大的价值,而不是被初始值覆盖了

    本题题目中 只包含正整数的非空数组,所以非0下标的元素初始化为0就可以了。

  4. 遍历顺序:如果使用一维dp数组,物品遍历的for循环放在外层,遍历背包的for循环放在内层,且内层for循环倒序遍历!

    // 开始 01背包
    for(int i = 0; i < nums.size(); i++) {
        for(int j = target; j >= nums[i]; j--) { // 每一个元素一定是不可重复放入,所以从大到小遍历
            dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);
        }
    }
    
  5. debug:打印dp数组

代码

class Solution {
    public boolean canPartition(int[] nums) {
        //题目写了数组非空
        int len = nums.length;
        int sum = 0;
        for(int num : nums) sum += num;
        //如果是奇数则没有意义,不能平分
        if((sum % 2) != 0) return false;
        int target = sum / 2;
        int[] dp = new int[target + 1];
        //初始化全是0:dp[0] = 0,其他的需要初始化非负最小整数,不能让初始化数字覆盖掉我们计算的值
        for(int i = 0; i < len; i++) {
            //物品 i 的重量是 nums[i],其价值也是 nums[i]
            for(int j = target; j >= nums[i]; j--) {
                dp[j] = Math.max(dp[j], (dp[j - nums[i]] + nums[i]));
            }

            //剪枝一下,每一次完成內層的for-loop,立即檢查是否dp[target] == target,優化時間複雜度(26ms -> 17ms)

            if(dp[target] == target) return true;
        }

        return dp[target] == target;
    }
}
  • 时间复杂度:O(n^2)
  • 空间复杂度:O(n),虽然dp数组大小为一个常数,但是大常数

总结

这道题目就是一道01背包应用类的题目,需要我们拆解题目,然后套入01背包的场景。

01背包相对于本题,主要要理解,题目中物品是nums[i],重量是nums[i],价值也是nums[i],背包体积是sum/2。

看代码的话,就可以发现,基本就是按照01背包的写法来的。

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

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

相关文章

C++:继承的概念和用法

文章目录 继承的定义基类和派生类的对象赋值转换继承中的作用域派生类的默认成员函数几个继承小点继承理论的演示 菱形继承和菱形虚拟继承虚拟继承 本篇主要总结的内容有 什么是继承继承的一些概念菱形继承和虚拟继承继承的优缺点对比 继承的定义 继承是代码复用的一种重要手…

Redis 主从复制,哨兵,集群——(1)主从复制篇

目录 1. Redis 主从复制是什么&#xff1f; 2. Redis 主动复制能干嘛&#xff1f; 2.1 读写分离 2.2 容灾恢复 2.3 数据备份 2.4 水平扩展支撑高并发 3. Redis 主从复制配置项 3.1 配从库不配主库 3.2 权限密码配置 3.3 基本操作命令 4. 案例演示 4.1 案例说明 4.…

leetCode 647.回文子串 动态规划 + 优化空间 / 中心扩展法 + 双指针

647. 回文子串 - 力扣&#xff08;LeetCode&#xff09; 给你一个字符串 s &#xff0c;请你统计并返回这个字符串中 回文子串 的数目。回文字符串 是正着读和倒过来读一样的字符串。子字符串 是字符串中的由连续字符组成的一个序列。具有不同开始位置或结束位置的子串&#x…

Springboot-MyBatisPlus-01

一 创建项目&#xff0c;选择spring boot 初始化&#xff0c;配置相关信息 第五步创建实体类 二 快速开发实体类的jar包--lombok <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12<…

Pycharm中终端不显示虚拟环境名解决方法

文章目录 一、问题说明&#xff1a;二、解决方法&#xff1a;三、重启Pycharm 一、问题说明&#xff1a; Pycharm中打开项目配置完需要的虚拟环境后&#xff0c;在Terminal&#xff08;终端&#xff09;中无法切换及显示当前需要运行代码的虚拟环境。 比如以下一种情况&#…

TOUGH2软件教程、CO2地质封存

TOUGH系列软件是由美国劳伦斯伯克利实验室开发的&#xff0c;旨在解决非饱和带中地下水、热运移的通用模拟软件。和传统地下水模拟软件Feflow和Modflow不同&#xff0c;TOUGH系列软件采用模块化设计和有限积分差网格剖分方法&#xff0c;通过配合不同状态方程&#xff08;EOS模…

人体分割模型ACE2P与M2FP,解析人脸人体各部件属性,语义化分析

前言 在做某任务的时候&#xff0c;需要对人物图片进行预处理。 预处理的要求就是要将图片中的人物各部件分割出来&#xff0c;标识为各种不同颜色&#xff0c;比如脸部为蓝色&#xff0c;脖颈部位绿色&#xff0c;其他地方为红色 最初任务使用的PaddleSeg中基于CelebAMask-HQ…

C# RestoreFormer 图像(人脸面部)修复

效果 项目 代码 using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using OpenCvSharp; using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.Windows.Forms;namespace 图像修复 {pu…

优维低代码实践:片段

优维低代码技术专栏&#xff0c;是一个全新的、技术为主的专栏&#xff0c;由优维技术委员会成员执笔&#xff0c;基于优维7年低代码技术研发及运维成果&#xff0c;主要介绍低代码相关的技术原理及架构逻辑&#xff0c;目的是给广大运维人提供一个技术交流与学习的平台。 优维…

Unity3D 基础——使用 Vector3.Distance 计算两个物体之间的距离

Vector3-Distance - Unity 脚本 APIhttps://docs.unity.cn/cn/current/ScriptReference/Vector3.Distance.html 1.在场景中新建两个 Cube 立方体&#xff0c;在 Scene 视图中将两个 Cude的位置错开。 2.新建 C# 脚本 Distance.cs&#xff08;写完记得保存&#xff09; using …

PS 学习笔记

书籍&#xff1a;Photoshop 2022从入门到精通-敬伟-微信读书 1. PS 常用快捷键 复位右侧基本工作栏&#xff1a;【窗口】-【工作区】- 【复位基本功能】 Ctrl 鼠标滚轮&#xff1a;主界面图片左右滚动Shift 鼠标滚轮&#xff1a;主界面图片上下滚动Alt 鼠标滚轮&#xff1…

StarUML的介绍与使用

文章目录 简介视图StarUML创建视图类图用例图时序图 简介 UML&#xff1a;统一建模语言&#xff0c;用模型元素组成的不同视图从各个维度来描述系统 StarUML为常用系统建模工具之一 视图 常见视图的概念可参考&#xff1a;UML常见的几种视图 包括&#xff1a;用例图、顺序图…

联想G50笔记本直接使用F键功能(F1~F12)需要在BIOS设置关闭热键功能可以这样操作!

如果开启启用热键模式按F1就会出现FnF1的效果&#xff0c;不喜欢此方式按键的用户可以进入BIOS设置界面停用热键模式即可。 停用热键模式方法如下&#xff1a; 1、重新启动笔记本电脑&#xff0c;当笔记本电脑屏幕出现Lenovo标识的时候&#xff0c;立即按FnF2进入BIOS设置界面…

ssm+vue的养老院老人健康监护平台(有报告)。Javaee项目,ssm vue前后端分离项目。

演示视频&#xff1a; ssmvue的养老院老人健康监护平台&#xff08;有报告&#xff09;。Javaee项目&#xff0c;ssm vue前后端分离项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系…

从入门到进阶 之 ElasticSearch 节点配置 集群篇

&#x1f339; 以上分享 ElasticSearch 安装部署&#xff0c;如有问题请指教写。&#x1f339;&#x1f339; 如你对技术也感兴趣&#xff0c;欢迎交流。&#x1f339;&#x1f339;&#x1f339; 如有需要&#xff0c;请&#x1f44d;点赞&#x1f496;收藏&#x1f431;‍&a…

基于SSM+Vue的咖啡销售系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

全面中文大语言模型评测来啦!香港中文大学最新研究

ChatGPT 的一声号角吹响了2023年全球大语言模型的竞赛。 2023年初以来&#xff0c;来自工业界和研究机构的各种大语言模型层出不穷&#xff0c;特别值得一提的是&#xff0c;中文大语言模型也如雨后春笋般&#xff0c;在过去的半年里不断涌现。 与此同时&#xff0c;和如何训…

Android 10 中的隐私权变更

Android 10 中的隐私权变更 重大变更外部存储访问权限范围限定为应用文件和媒体在后台运行时访问设备位置信息需要权限以 Android 9 或更低版本为目标平台时自动授予访问权限在设备升级到 Android 10 后访问针对从后台启动 Activity 的限制标识符和数据移除了联系人亲密程度信息…

Go语言入门心法(六): HTTP面向客户端|服务端编程

Go语言入门心法(一): 基础语法 Go语言入门心法(二): 结构体 Go语言入门心法(三): 接口 Go语言入门心法(四): 异常体系 Go语言入门心法(五): 函数 一:go语言面向web编程认知 Go语言的最大优势在于并发与性能,其性能可以媲美C和C,并发在网络编程中更是至关重要 使用http发送请…

hal开发之hidl/aidl支持的绑定式直通式详细讲解

为啥有hidl呢&#xff1f; 这个问题其实网络上答案比较多&#xff0c;属于android想要让厂商快速升级解耦制定的&#xff0c;即把原来系统framework和厂商耦合的hal在同一个个system.img进行剥离开&#xff0c;把厂商相关的放到vendor.img&#xff0c;aosp系统公共部分framewo…