代码随想录算法训练营day42 | 01背包问题,你该了解这些!,01背包问题,你该了解这些! 滚动数组 , 416. 分割等和子集

news2024/11/28 2:39:03

代码随想录算法训练营day42 | 背包理论基础,背包理论基础(滚动数组), 416. 分割等和子集

  • 1、01背包理论基础
    • 背包问题概述
    • 01背包
    • 二维dp数组01背包案例
  • 2、01背包理论基础(滚动数组)
  • 3、 416. 分割等和子集
    • 解法一:动态规划


1、01背包理论基础

教程视频:https://www.bilibili.com/video/BV1cg411g7Y6

背包问题概述

在这里插入图片描述重点掌握01 背包和完全背包即可。

01背包

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

暴力解法:每一件物品其实只有两个状态,取或者不取,所以可以使用回溯法搜索出所有的情况,那么时间复杂度就是 o ( 2 n ) o(2^n) o(2n),这里的n表示物品数量。

因为暴力的解法是指数级别的时间复杂度。进而才需要动态规划的解法来进行优化!

二维dp数组01背包案例

背包最大重量为4。
物品为:

物品重量价值
物品0115
物品1320
物品2430

问背包能背的物品最大价值是多少?

动态规划分析:

  1. 确定dp数组以及下标的含义
    这里使用二维数组解决。即dp[i][j] 表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少。
物品编号(i) \ 背包容量(j)01234
物品00015151515
物品110dp[1][1]dp[1][2]dp[1][3]dp[1][4]
物品220dp[2][1]dp[2][2]dp[2][3]dp[2][4]
  1. 确定递推公式
    有两个方向推出来dp[i][j]:
    不放物品i :由dp[i - 1][j]推出,即背包容量为j,里面不放物品i的最大价值,此时dp[i][j]就是dp[i - 1][j]。(其实就是当物品i的重量大于背包j的重量时,物品i无法放进背包中,所以被背包内的价值依然和前面相同。)在表格中表现为正上方格子值+当前行的物品价值。
    放物品i:由dp[i - 1][j - weight[i]]推出,dp[i - 1][j - weight[i]] 为背包容量为j - weight[i]的时候不放物品i的最大价值,那么dp[i - 1][j - weight[i]] + value[i] (物品i的价值),就是背包放物品i得到的最大价值。

    因此dp[i][j]=Math.max(dp[i-1][j], dp[i-1][j-weight[i]]+value[i]);

  2. dp数组如何初始化
    背包容量为0时,最大价值为0,即dp[*][0]=0;
    对第一件物品来说,背包容量不够时最大价值为0;从能放进背包那一刻开始,背包的最大价值等于value[0]。
    剩余位置初始为什么数值都可以,因为都会被覆盖。

  3. 确定遍历顺序
    双层for循环,一层遍历物品,一层遍历背包。
    在本题中,只要保持dp[<i][<=j]处都有值即可,因此两层循环顺序调换并不影响最终结果。

  4. 举例推导dp数组
    做动态规划的题目,最好的过程就是自己在纸上举一个例子把对应的dp数组的数值推导一下,然后再动手写代码!

class Solution{
    public static void main(String[] args) {
        int[] weight = {1,3,4};
        int[] value = {15,20,30};
        int bagSize = 4;
        testBagProblem(weight,value,bagSize);
    }

	public static void testBagProblem(int[] weight, int[] value, int bagSize){
		// 创建dp数组
		int[][] dp = new int[weight.length][bagSize+1];
		// 初始化dp数组
		for(int i=0;i<weight.length;i++){
			dp[i][0]=0;
		}
		for(int i=0;i<=bagSize;i++){
			if(i>=weight[0]){
				dp[0][i]=value[0];
			}
			dp[0][i]=0;
		}
		// 填充dp数组
		for(int i=1;i<weight.length;i++){
			for(int j=1;j<=bagSize;j++){
			if(j>=weight[i]){
				//当前背包的容量大于等于当前物品i的时候,比较两种情况下,哪种最大价值最大
				dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-weight[i]]+value[i]);
			}else{
				dp[i][j] = dp[i-1][j];
			}
			}
		}
		//打印
		for (int i = 0; i < weight.length; i++) {
            for (int j = 0; j <= bagSize; j++) {
                System.out.print(dp[i][j] + "\t");
            }
            System.out.println("\n");
        }
	}
}

2、01背包理论基础(滚动数组)

教程视频:https://www.bilibili.com/video/BV1BU4y177kY
滚动数组,其实就是将二维dp表格解决降为一维dp数组,一些录友当时还表示比较困惑。

  1. 确定dp数组的定义
    在一维dp数组中,dp[j]表示:容量为j的背包,所背的物品价值可以最大为dp[j]。
  2. 一维dp数组的递推公式
    dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
  3. 一维dp数组如何初始化
    下标0的位置,即dp[0]初始为0。
    从递归公式可以看出,dp数组在推导的时候一定是取价值最大的数,所以如果题目给的价值都是正整数,那么非0下标都初始化为0就可以了。
  4. 一维dp数组遍历顺序
    此时因为将对于物品的遍历压缩到一位数组中,需要先遍历物品,再遍历背包容量。
    为了利用上次循环的状态,同时保证物品i只被放入一次,背包容量需要倒序遍历。
  5. 举例推导dp数组
class Solution{
    public static void main(String[] args) {
        int[] weight = {1,3,4};
        int[] value = {15,20,30};
        int bagSize = 4;
        testBagProblem(weight,value,bagSize);
    }
    public static void testBagProblem(int[] weight, int[] value,int bagSize){
    	//定义dp数组
    	int[] dp = new int[bagSize+1];
    	//dp数组初始化(默认全为0,可以不显示初始化)
    	for(int i=0;i<weight.length;i++){
    		
    		for(int j=bagSize;j>=0;j--){
	    		if(j>weight[i]){
	    			dp[j] = Math.max(dp[j], dp[j-weight[i]]+value[i]);
	    		}//这里可以化简,还可以把if判断放在for循环条件中
	    		//else{
	    			//dp[j]=dp[j];
	    		//}
    		}
    		//打印dp数组
	        for (int j = 0; j <= bagSize; j++){
	            System.out.print(dp[j] + " ");
	        }
    	}
    }
}

3、 416. 分割等和子集

教程视频:https://www.bilibili.com/video/BV1rt4y1N7jE
在这里插入图片描述

解法一:动态规划

注意题目描述中商品是不是可以重复放入。所以本题中,要使用的是01背包,因为元素只能用一次。

只有确定了如下四点,才能把01背包问题套到本题上来:
1、背包的体积为sum / 2
2、背包要放入的商品(集合里的元素)重量为 元素的数值,价值也为元素的数值
3、背包如果正好装满,说明找到了总和为 sum / 2 的子集。
4、背包中每一个元素是不可重复放入。

  1. 确定dp数组以及下标的含义
    dp[j]表示 背包总容量(所能装的总重量)是j,放进物品后,背的最大重量为dp[j]。
  2. 确定递推公式(物品i的重量是nums[i],其价值也是nums[i])
    dp[j]=Math.max(dp[j], dp[j-nums[i]]+nums[i]);
  3. dp数组如何初始化
    首先dp[0]是0。
    题目给的价值都是正整数,所以非0下标都初始化为0。
  4. 确定遍历顺序
    同理滚动数组,外层for循环遍历nums中数值,内层for循环反向遍历背包容量。
  5. 举例推导dp数组
    dp[j]的数值一定是小于等于j的。
    如果dp[j] == sum/2,即背包正好装满,说明集合中的子集总和正好可以凑成sum/2。
class Solution {
    public boolean canPartition(int[] nums) {
        int sum=0;
        for(int i=0;i<nums.length;i++){
            sum+=nums[i];
        }
        //总和为奇数,不能平分
        if(sum%2==1){return false;}

        int[] dp = new int[sum/2+1];
        for(int i=0;i<nums.length;i++){
            for(int j=sum/2;j>=nums[i];j--){
                //物品 i 的重量是 nums[i],其价值也是 nums[i]
                dp[j]=Math.max(dp[j], dp[j-nums[i]]+nums[i]);
            }
        }
        return dp[sum/2] == sum/2;
    }
}

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

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

相关文章

Redis持久化-Redis主从-Redis哨兵-Redis分片集群

主要内容 Redis持久化Redis主从Redis哨兵Redis分片集群 Redis持久化 Redis有两种持久化的方案: RDB持久化AOF持久化 1. RDB持久化 RDB全称Redis Database Backup file&#xff08;Redis数据备份文件&#xff09;&#xff0c;也被叫做Redis数据快照。简单来说就是把内存中的所…

数字化时代下,制造业企业应该这样做仓库管理

透过现象看本质&#xff0c;在传统的仓储管理中都存在着以下问题&#xff1a; 1.信息化水平较低&#xff0c;以人工为主&#xff0c;以纸张为主&#xff0c;效率低下&#xff0c;容易出现错误&#xff1b; 2.信息流的不对称性&#xff0c;各个过程之间的联系不紧密&#xff0c;…

【高危】Apache Spark UI shell 命令注入漏洞(POC)

漏洞描述 该漏洞是针对此前CVE-2022-33891漏洞的修订&#xff0c;原有漏洞通告中认为3.1.3版本已修复该漏洞&#xff0c;后发现仍受到影响&#xff0c;3.1.3版本已不再维护&#xff0c;官方建议升级至3.4.0版本。 Apache Spark是美国阿帕奇&#xff08;Apache&#xff09;软件…

在这里总有一款高温介电温谱仪适合您(GWJDN-300/600/1000型多种可选)

GWJDN-300型多用途型高温介电温谱仪 关键词&#xff1a;高温介电&#xff0c;变温&#xff0c;电容&#xff0c;损耗 GWJDN-300高温介电温谱仪是一款专门用于评估电介质材料高温介电机制&#xff08;材料极化、储能、驰豫、相变、微结构变化、分子团重新取向等&#xff09;的…

远程控制电脑怎么弄? 远程控制电脑方法介绍

如何免费远程控制电脑&#xff1f; “你好&#xff0c;你知道任何可靠的免费Windows远程控制软件吗&#xff1f;我需要在工作电脑和家用电脑之间进行远程控制&#xff0c;因为我将出差数周。有什么好用的远程控制电脑方法吗&#xff1f;提前致谢&#xff01;” 电脑之间如何…

ChatGPT学习指南

主旨 大家好&#xff0c;我是五竹。心血来潮整理了这份手册并且将为小白们持续更新和GPT相关的资源和教程&#xff0c;专注于打造一部最好的GPT入门指南。此文档永久免费在线查看&#xff0c;欢迎大家转发、收藏、点赞支持&#xff01;后面会在文档中更新&#xff1a;ChatGPT学…

优秀互联网产品经理必备的10张业务图谱

作为离产品最近的人&#xff0c;产品经理是团队的交通枢纽&#xff0c;链接运营的需求和程序员的开发工作。面对庞杂多面的工作&#xff0c;今天小编和大家聊聊产品经理在工作各环节想要精进专业&#xff0c;都需要具备哪些能力。 01学习篇 持续学习的概念早已被大家接受&#…

海量数据同步到DDM(oracle到mysql)

1、由于oracle的rownum性能&#xff0c;所以通过主键ID实现分页&#xff1b; 2、数据可能存在重复&#xff0c;批量插入mysql使用insert ignore语法&#xff1b; 3、DDM数据库&#xff0c;过千万后并发插入&#xff0c;性能就很差&#xff1a;采用单线程一千条批量插入&#…

MySQL--索引--0427--0507

目录 1. MySQL是如何处理数据的 2. MySQL与磁盘的关系 3. MySQL与磁盘交互的基本单位 4.MySQL和磁盘之间联系的总结 5.索引的理解 5.1 理解单个page 5.2 理解多个page 5.3 为什么采用B树 5.4 聚簇索引 和 非聚簇索引 5.5 聚簇索引 和 非聚簇索引下的普通索引 6.索引操作…

Spring 注解之@RestController与@Controller的区别

目录 1&#xff1a;介绍 2&#xff1a;区别 3&#xff1a;总体来说 4&#xff1a;社区地址 1&#xff1a;介绍 RestController 和 Controller 是 Spring MVC 中常用的两个注解&#xff0c;它们都可以用于定义一个控制器类。 2&#xff1a;区别 返回值类型不同&#xff1a;…

STM32单片机声控语音识别RGB彩灯多种模式亮度可调WS2812彩灯

实践制作DIY- GC0129-语音识别RGB彩灯 一、功能说明&#xff1a; 基于STM32单片机设计-语音识别RGB彩灯 二、功能介绍&#xff1a; STM32F103C系列最小系统板5VUSB电源64个灯珠的WS2812灯板1个开关键&#xff08;3档亮度调节&#xff09;1个模式切换键&#xff08;白灯 红灯…

软件测试4年从外包15K跳槽去字节 38K+12,啃完这份笔记你也可以

转行做软件测试已经是第4个年头&#xff0c;一直是一个不温不火的小职员&#xff0c;本本分分做着自己的事情&#xff0c;觉得自己的工作已经遇到了瓶颈&#xff0c;一个偶然的机会&#xff0c;获得了一份软件测试全栈知识点学习笔记&#xff0c;通过几个月的学习&#xff0c;5…

git提交代码到GitLab步骤及拉取远程分支内容

一、本地建立一个空文件夹 点击鼠标右键点击红色箭头方向 Git Hash Here 二、git init 进行初始化 这个时候文件夹中会出现 .git 文件夹 三、添加远程仓库地址 git remote add origin (address) # 添加远程仓库地址 address是远程仓库代码链接 四、如果有分支把远程分支拉到…

跨设备开发的未来:多端能力服务统一技术

多端能力服务统一&#xff08;Multi-Experience Service Orchestration&#xff0c;MESO&#xff09;是一种技术和服务架构的概念&#xff0c;旨在为多种终端设备提供统一的用户体验和功能。它解决了在不同终端设备上使用不同应用程序和服务时出现的问题&#xff0c;使得用户可…

Springboot +Flowable,会签、或签简单使用(二)

一.简介 **会签&#xff1a;**在一个流程中的某一个 Task 上&#xff0c;这个 Task 需要多个用户审批&#xff0c;当多个用户全部审批通过&#xff0c;或者多个用户中的某几个用户审批通过&#xff0c;就算通过。 例如&#xff1a;之前的请假流程&#xff0c;假设这个请假流程…

[iOS]消息传递和消息转发

消息转发和消息传递 消息转发 iOS的消息转发是指当一个对象收到一个无法响应的消息时&#xff0c;其会通过多个方法转发该消息&#xff0c;直到能够响应为止。具体来说&#xff0c;当消息接收者无法响应某个方法时&#xff0c;Objective-C消息传递机制会按照以下顺序进行转发…

路径规划算法:基于绯鲵鲣算法的路径规划算法- 附代码

路径规划算法&#xff1a;基于绯鲵鲣优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于绯鲵鲣优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化算法…

java读取word文档内容

首先在pom文件引入依赖&#xff1a; <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.0.0</version> </dependency> <dependency><groupId>org.apache.poi</groupId&g…

Databend 开源周报第 93 期

Databend 是一款现代云数仓。专为弹性和高效设计&#xff0c;为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务&#xff1a;https://app.databend.cn 。 Whats On In Databend 探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。 改进 Databend …

冠珠华珍岩板闪现人民日报美好博物馆,彰显民族品牌魅力

行业唯一&#xff01;亮相美好博物馆 一块为中国品牌发声 为了贯彻落实品牌强国战略&#xff0c;展现中国优秀品牌成果&#xff0c;5月10日&#xff0c;值第7个中国品牌日来临之际&#xff0c;由人民日报社特别打造的美好博物馆主题快闪店惊艳亮相上海世博展览中心。 作为连…