代码随想录 动态规划||01背包理论 416

news2025/7/19 16:51:15

Day36

01背包理论基础

01背包

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

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

  • 背包最大重量为4。

物品为:

重量

价值

物品0

1

15

物品1

3

20

物品2

4

30

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

二维dp数组01背包

  • 确定dp数组以及下标的含义

  • dp[i] [j] 表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少

  • 确定递推公式

  • 那么可以有两个方向推出来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] = max(dp[i - 1] [j], dp[i - 1] [j - weight[i]] + value[i]);

  • dp数组如何初始化

  • 如果背包容量j为0的话,即dp[i] [0],无论是选取哪些物品,背包价值总和一定为0。

  • dp[0] [j],即:i为0,存放编号0的物品的时候,各个容量的背包所能存放的最大价值。

那么很明显当 j < weight[0]的时候,dp[0] [j] 应该是 0,因为背包容量比编号0的物品重量还小。

当j >= weight[0]时,dp[0] [j] 应该是value[0],因为背包容量放足够放编号0物品。

  • 其他下标初始为什么数值都可以,因为都会被覆盖

  • 确定遍历顺序

  • 都可以,但是先遍历物品更好理解

public class 零一背包 {
    public static void main(String[] args) {
        int[] weight = {1,3,4};
        int[] value = {15,20,30};
        int bagSize = 4;
        testWeightBagProblem(weight,value,bagSize);
        //0    15    15    15    15    
        //0    15    15    20    35    
        //0    15    15    20    35
    }

    public static void testWeightBagProblem(int[] weight, int[] value, int bagSize) {
        int[][] dp = new int[weight.length][bagSize + 1];//初始化dp数组
        for (int j = weight[0]; j <= bagSize; j++){//当背包容量为0的时候,dp[i][0] = 0
            dp[0][j] = value[0];//这里处理的是dp[0][j],当容量比第一个物品重量大,才不为零
        }
        for (int i = 1; i < weight.length; i++){
            for (int j = 1; j <= bagSize; j++){
                if (j < weight[i]){//如果第i个物品的重量比背包容量都大,一定放不进去
                    dp[i][j] = dp[i - 1][j];
                }else{//取不放第i个物品,和放第i个物品(但有可能要把之前放进去的物品取出)这两种情况最大值
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
                }
            }
        }
        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();//打印dp数组
        }
    }
}

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

一维dp数组(滚动数组)

  • 对于背包问题其实状态都是可以压缩的。

  • 在使用二维数组的时候,递推公式:dp[i] [j] = max(dp[i - 1] [j], dp[i - 1] [j - weight[i]] + value[i]);

  • 其实可以发现如果把dp[i - 1]那一层拷贝到dp[i]上,表达式完全可以是:dpi = max(dpi, dpi] + value[i]);

与其把dp[i - 1]这一层拷贝到dp[i]上,不如只用一个一维数组了,只用dp[j](一维数组,也可以理解是一个滚动数组)。

  • 这就是滚动数组的由来,需要满足的条件是上一层可以重复利用,直接拷贝到当前层。

  • 确定dp数组的定义

  • 在一维dp数组中,dp[j]表示:容量为j的背包,所背的物品价值可以最大为dp[j]。

  • 一维dp数组的递推公式

  • dp[j]为 容量为j的背包所背的最大价值,那么如何推导dp[j]呢?

  • dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

  • 一维dp数组如何初始化

  • dp[j]表示:容量为j的背包,所背的物品价值可以最大为dp[j],那么dp[0]就应该是0,因为背包容量为0所背的物品的最大价值就是0。

  • 如果题目给的价值都是正整数那么非0下标都初始化为0就可以了

  • 一维dp数组遍历顺序

  • 倒序遍历是为了保证物品i只被放入一次

public class 一维背包 {

    public static void main(String[] args) {
        int[] weight = {1, 3, 4};
        int[] value = {15, 20, 30};
        int bagSize = 4;
        testWeightBagProblem(weight, value, bagSize);
        //0    15    15    20    35    
    }

    public static void testWeightBagProblem(int[] weight, int[] value, int bagSize) {
        int[] dp = new int[bagSize + 1];//dp数组容量为bagSize + 1
        for (int i = 0; i < weight.length; i++){//遍历物品
            for (int j = bagSize; j >= weight[i]; j--){//遍历背包,倒序遍历,而且只更新容量比当前物品重量大的部分
                dp[j] = Math.max(dp[j],dp[j - weight[i]] + value[i]);
            }
        }
        for (int j = 0; j <= bagSize; j++){
            System.out.print(dp[j] + "\t");
        }
    }
}

416. 分割等和子集

力扣题目链接

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

思路

  • 可以转换成01背包问题

  • 每个元素都是物品,重量和价值都是nums[i],背包容量是sum / 2

  • 看背包能不能正好装满

代码

class Solution {
    public boolean canPartition(int[] nums) {
        int sum = 0;
        for (int num : nums) {
            sum += num;//先计算数组元素的和
        }
        if (sum % 2 == 1) return false;//如果和是奇数,那就无法分割
        int target = sum / 2;//转换成要从数组中找元素,这些元素和能不能正好是target
        int[] dp = new int[target + 1];//背包容量是target,看能不能装满
        for (int i = 0; i < nums.length; i++){//遍历数组,就是物品,每个物品的重量和价值都是nums[i]
            for (int j = target; j >= nums[i]; j--){
                dp[j] = Math.max(dp[j],dp[j - nums[i]] + nums[i]);
            }
        }
        return dp[target] == target;//最后要看看能不能正好装满
    }
}

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

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

相关文章

Java学习笔记 --- Servlet(1)

一、Servlet技术 1、Servlet基本介绍 1、Servlet 是 JavaEE 规范之一。规范就是接口 2、Servlet 就 JavaWeb 三大组件之一。三大组件分别是&#xff1a;Servlet 程序、Filter 过滤器、Listener 监听器。 3、Servlet 是运行在服务器上的一个 java 小程序&#xff0c;它可以…

院士交锋,专家论道|NLP大模型技术与应用十大挑战,剑指AI未来

2023年2月24日下午&#xff0c;第四届OpenI/O启智开发者大会NLP大模型分论坛在深圳人才研修院隆重举办。NLP大模型论坛会议现场众多NLP领域顶级专家学者与多家国产NLP大模型开发团队汇聚一堂&#xff0c;学术界与产业界破圈交流&#xff0c;激荡尖端思想、分享前沿动态&#xf…

Linux学习第二十二节-网卡IP设置

1.修改网卡IP地址 方式一&#xff1a;通过修改网卡配置文件修改 网卡配置文件位置&#xff1a; /etc/sysconfig/network-scripts/网卡名 #ifconfig 表示用于显示和设置网卡的参数 #ip addr 表示用于显示和设置网卡的参数 #systemctl restart network 表示重启网络 …

Spark Join大小表

Spark Join大小表无法广播过滤后大小表数据分布均匀大小表 : 大小表尺寸相差 3 倍以上 Join 优先考虑 BHJ小表的数据量 > 广播阈值时&#xff0c;优先考虑 SHJ 无法广播 大表 100GB、小表 10GB&#xff0c;都远超广播变量阈值 当小表的尺寸 > 8GB时&#xff0c;创建广…

剑指-Offer-30-包含min函数的栈

剑指 Offer 30.包含min函数的栈 题目描述&#xff1a; 定义栈的数据结构&#xff0c;请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中&#xff0c;调用 min、push 及 pop 的时间复杂度都是 O(1)。 示例&#xff1a; MinStack minStack new MinStack(); minSt…

Python中的错误是什么,Python中有哪些错误

7.1 错误(errors) 由于Python代码通常是人类编写的&#xff0c;那么无论代码是在解释之前还是运行之后&#xff0c;或多或少总会出现一些问题。 在Python代码解释时遇到的问题称为错误&#xff0c;通常是语法和缩进问题导致的&#xff0c;这些错误会导致代码无法通过解释器的解…

2023年绿色建筑国际会议(ICoGB 2023)

2023年绿色建筑国际会议&#xff08;ICoGB 2023&#xff09; 重要信息 会议网址&#xff1a;www.icogb.org 会议时间&#xff1a;2023年5月19-21日 召开地点&#xff1a;斯德哥尔摩 截稿时间&#xff1a;2023年4月1日 录用通知&#xff1a;投稿后2周内 收录检索&#xff…

剑指 Offer 61 扑克牌中的顺子

摘要 扑克牌中的顺子 一、集合 Set 遍历 根据题意&#xff0c;此5张牌是顺子的 充分条件 如下&#xff1a; 除大小王外&#xff0c;所有牌 无重复 &#xff1b;设此5张牌中最大的牌为max&#xff0c;最小的牌为min&#xff08;大小王除外&#xff09;&#xff0c;则需满足…

深入理解浏览器解析机制和XSS向量编码

目录 1、HTML解析 字符实体(character entities) HTML字符实体(HTML character entities) 字符引用(character references) 在HTML中有五类元素 五类元素的区别如下 深入了解下RCDATA元素 2、URL解析 3、JavaScript解析 4、解析流 1、HTML解析 从XSS的角度来说&…

es倒排索引原理

1、简介 网上看到的一篇文章&#xff0c;对Lucene的倒排索引是如何执行的&#xff0c;说的比较易懂&#xff0c;就转过来分享下。 Elasticsearch是通过Lucene的倒排索引技术实现比关系型数据库更快的过滤。特别是它对多条件的过滤支持非常好&#xff0c;比如年龄在18和30之间&a…

kubeadm安装K8S(集群)

前言市面上很多k8s的安装工具&#xff0c;作为产品的设计者和推广者&#xff0c;K8S组织也知道自己的产品部署起来十分的困难&#xff0c;于是把开源爱好者写的工具kubeadmn收编为正规军&#xff0c;纳入到了自己的麾下。为什么我们要用kubeadmn来部署&#xff1f;因为kubeadm不…

【代码实践】DeepBDC for few-shot learning代码运行

DeepBDC是Jiangtao Xie等人在CVPR2022上提出的few-shot classification方法&#xff0c;论文全名为“Joint Distribution Matters: Deep Brownian Distance Covariance for Few-Shot Classification”。本文旨在记录在Window系统下运行该官方代码&#xff08;https://github.co…

Linux学习第二十四节-Podman容器

一、容器的概念 容器是由一个或多个与系统其余部分隔离的进程组成的集合。我们可以理解为“集装箱”。 集装箱是打包和装运货物的标准方式。它作为一个箱子进行标记、装载、卸载&#xff0c;以及从一个 位置运输到另一个位置。该容器的内容与其他容器的内容隔离&#xff0c…

传统企业数字化转型真的有必要吗?应该如何做转型?

随着数字经济的快速发展&#xff0c;各行各业数字化转型成为必然。从最初的信息化建设&#xff0c;到数字企业、数字政府建设&#xff0c;再到如今的数字经济建设&#xff0c;传统企业在数字化转型中的作用越来越大。与此同时&#xff0c;数字化转型对传统企业提出了更高的要求…

【Java开发面试】AHXX面试总结

1. java中常用的集合有哪些 java中常用的集合类有List,Set,Map,其中List和Set继承了Collection。 List的实现类有&#xff1a;ArrayList&#xff0c;LinkedList&#xff0c;Vector&#xff0c;Stack Set的实现类有&#xff1a;TreeSet&#xff0c;HashSet Map的实现类有&#…

MySQL运维篇之读写分离

04、读写分离 4.1、介绍 读写分离&#xff0c;简单地说是把对数据库的读和写操作分开&#xff0c;以对应不同的数据库服务器。主数据库提供写操作&#xff0c;从数据库提供读操作&#xff0c;这样能有效地减轻单台数据库的压力。 通过Mycat即可轻易实现上述功能&#xff0c;…

02_Linux终端操作,shell命令,软件安装,文件系统结构,磁盘管理

目录 终端操作 常用Shell命令 Ubuntu软件安装方法 Ubuntu文件系统结构 绝对路径和相对路径 Ubuntn下磁盘管理 终端操作 打开终端快捷键Ctrlaltt 或鼠标右键 常用Shell命令 1.目录信息查看命令ls ls -a 显示目录所有文件及文件夹,包括隐藏文件,比如以.开头的 ls -l…

Synopsys Sentaurus TCAD系列教程之--Sprocess(SmallMOS_2D3D) 解析

SmallMOS_2D3D解析 #header## STI depth set sti_depth 0.15 ## Half STI width set sti_width sti_width ## Half gate length set gate_len <lg/2> ## SD length (from center) set sd_len [expr $gate_len0.05]#endheader## X lines line x location 0.0 spacing 0.…

OSI ARP TCP-IP HDCP

OSI七层参考模型分层名称基本功能应用层用户与网络、应用程序与网络的接口&#xff0c;直接向用户提供服务表示层处理用户信息的表示问题&#xff0c;如编码、数据格式转换和加密解密会话层组织和协调两个会话进程之间的通信传输层应用进程之间的连接&#xff0c;提供端到端的服…

Coremail邮件系统全新上线存档邮箱功能

邮箱积累邮件太多&#xff0c;搜索起来又慢又麻烦&#xff01; 我的重要邮件忘记下载丢失了&#xff01;14天自动删除太难了&#xff01; 有没有可能重要邮件自动存档&#xff0c;解救一下“遗忘星”人&#xff1f; 在我们日常工作中&#xff0c;邮件是最经常使用的办公工具之一…