3.10-动态规划-01背包问题

news2024/10/10 10:23:51

问题描述,给定n种物品和一个背包。物品 i 的重量是 wi ,其价值为 vi ,背包的容量为 c ,问应该如何选择装入背包中的物品,使得装入背包的物品总价值最大?

写在前面

 dp数组的含义--dp[i][j]表述容量为j 已经对前i件物品做出选择时0-1背包的最优值

递推关系是什么?

dp[i][j]=max ( dp[i+1][j] , dp[i+1,j-w[i]]+v[i])   j>=wi 选择第i件物品,不选择第i件物品

dp[i][j]=dp[i+1][j]                                           j>wi   只能不选择第i件物品,因为背包装不下

如何初始化--首先从dp[i][j]的定义出发,如果背包容量j为0的话,即dp[i][0],无论是选取哪些物品,背包价值总和一定为0。

在看其他情况。状态转移方程 dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]); 可以看出i 是由 i-1 推导出来,那么i为0的时候就一定要初始化。dp[0][j],即:i为0,存放编号0的物品的时候,各个容量的背包所能存放的最大价值。

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

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

遍历顺序--要理解递归的本质和递推的方向

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

递归公式中可以看出dp[i][j]是靠dp[i-1][j]和dp[i - 1][j - weight[i]]推导出来的。

举例推导--省略

问题分析

在选择物品装入背包的时候,对每种物品只有两种选择,装入?不装入?

 最优子结构性质

这是一个特殊的整数规划问题:用公式表述为

 最优子结构性质证明(此处省略)

 递归关系

 

 j表示容量

i表示已经对前i键物品做出了取舍

dp[i][j]的含义表示为:当对前面i件物品做完选择,并且容量为j,产生的最大价值。

伪代码如下:

构造最优解

 背包问题是很多问题的原形,我们还要介绍一维数组写01背包问题的方法

  1. 确定dp数组的定义

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

  1. 一维dp数组的递推公式

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

dp[j]可以通过dp[j - weight[i]]推导出来,dp[j - weight[i]]表示容量为j - weight[i]的背包所背的最大价值。

dp[j - weight[i]] + value[i] 表示 容量为 j - 物品i重量 的背包 加上 物品i的价值。(也就是容量为j的背包,放入物品i了之后的价值即:dp[j])

此时dp[j]有两个选择,一个是取自己dp[j] 相当于 二维dp数组中的dp[i-1][j],即不放物品i,一个是取dp[j - weight[i]] + value[i],即放物品i,指定是取最大的,毕竟是求最大价值,

所以递归公式为:

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

可以看出相对于二维dp数组的写法,就是把dp[i][j]中i的维度去掉了。

  1. 一维dp数组如何初始化

关于初始化,一定要和dp数组的定义吻合,否则到递推公式的时候就会越来越乱

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

那么dp数组除了下标0的位置,初始为0,其他下标应该初始化多少呢?

看一下递归公式:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

dp数组在推导的时候一定是取价值最大的数,如果题目给的价值都是正整数那么非0下标都初始化为0就可以了。

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

那么我假设物品价值都是大于0的,所以dp数组初始化的时候,都初始为0就可以了。

  1. 一维dp数组遍历顺序

代码如下:

for(int i = 0; i < weight.size(); i++) { // 遍历物品
    for(int j = bagWeight; j >= weight[i]; j--) { // 遍历背包容量
        dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

    }
}

这里大家发现和二维dp的写法中,遍历背包的顺序是不一样的!

二维dp遍历的时候,背包容量是从小到大,而一维dp遍历的时候,背包是从大到小。

为什么呢?

倒序遍历是为了保证物品i只被放入一次!。但如果一旦正序遍历了,那么物品0就会被重复加入多次!

举一个例子:物品0的重量weight[0] = 1,价值value[0] = 15

如果正序遍历

dp[1] = dp[1 - weight[0]] + value[0] = 15

dp[2] = dp[2 - weight[0]] + value[0] = 30

此时dp[2]就已经是30了,意味着物品0,被放入了两次,所以不能正序遍历。

为什么倒序遍历,就可以保证物品只放入一次呢?

倒序就是先算dp[2]

dp[2] = dp[2 - weight[0]] + value[0] = 15 (dp数组已经都初始化为0)

dp[1] = dp[1 - weight[0]] + value[0] = 15

所以从后往前循环,每次取得状态不会和之前取得状态重合,这样每种物品就只取一次了。

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

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

相关文章

【计算机体系结构-03】ISA (Instruction Set Architecture) 指令集架构特性

1. 指令的类型 上一篇文章里主要介绍了几种机器模型&#xff0c;有机器模型后需要知道计算机有什么样的基本指令&#xff0c;接下来就来看看指令都有哪些类型。 [注]&#xff1a;以下指令主要为 MIPS 指令。 类型指令数据传输LD、ST、MFC1、MTC1、MFC0、MTC0计算ADD、SUB、AN…

Vue3和Vue2的slot-scope插槽用法

目录 &#x1f9e8;&#x1f9e8;&#x1f9e8;第一种插槽&#xff08;匿名插槽&#xff09; &#x1f9e8;&#x1f9e8;&#x1f9e8;第二种插槽&#xff08;具名插槽&#xff09;以及插槽简写 具名插槽的使用 &#x1f9e8;&#x1f9e8;&#x1f9e8;第三种插槽(作用域插…

使用HTTP代理后,网速反而变慢是什么原因?

如今越来越多的人利用HTTP代理开展业务&#xff0c;但在实际使用时&#xff0c;经常会有用户发现使用了HTTP代理后&#xff0c;网速非但没有变快&#xff0c;反而还更慢了。我们今天就来说说&#xff0c;这是什么原因造成的&#xff0c;从根本入手对于我们能更有利的解决问题。…

2.Spring IOC

目录 一.如何进行注册 二、如何进行注入 三、扫描注解的原理 反射文件操作 四、什么是IOC/DI&#xff1f; 五、演示使用Spring开发的案例&#xff1a;用户管理|登陆、注册 五、常见错误总结 1、注解使用Repository 2、UserController的构造方法注入&#xff1a; 3、…

【FreeRTOS】第一章:介绍

FreeRTOS是什么&#xff1f; Free和RTOS,Free就是免费的、自由的意思&#xff0c;RTOS 全称是 Real Time Operating System。中文名就是实时操作系统。可以看出FreeROTS 就是一个免费的 RTOS 类系统。这里要注意&#xff0c;RTOS 不是指某一个确定的系统&#xff0c;而是指一类…

联想电脑安装ubuntu18.04双系统超详细教程(23年最新教程,99%成功率)

文章目录前言电脑配置制作系统盘安装ubuntu系统更新显卡驱动安装wifi驱动完成前言 ubtuntu的长期支持版本现在应该已经出道21.04版本了&#xff0c;如果你对于版本没有要求的话&#xff0c;建议直接安装最新版ubuntu&#xff0c;因为新版的系统驱动都会进行更新&#xff0c;也…

自学 Java 怎么入门?

玩Java多年的老司机带你上车全面系统学习Java&#xff0c;并且还能教你如何学习才能在今年拿到一份不错的offer。 说到系统全面&#xff0c;就是以目前绝大部分公司招聘要求的知识内容为基准&#xff0c;毕竟我们学习Java都是为了高薪工作&#xff0c;《史记》中说”天下熙熙皆…

2.【SpringBoot源码】SpringBoot核心启动流程

目录 一、简介 二、创建SpringApplication对象 1)、推导出当前启动的项目的类型 2)、设置Initializer初始化器 3)、初始化Listener监听器 4)、反推出main方法所在的Class对象 三、运行SpringApplication#run(java.lang.String...)方法 1)、获取运行监听器 2)、发布…

unity使用对象池实现冲锋留下的残影效果

目录 效果展示 实现思路 残影代码 对象池代码 控制冲刺产生残影 CD冷却图标 效果展示 实现思路 对象池&#xff0c;有想要用的物体时可以从池子里取&#xff0c;用完再放回去。 因为在生成残影再销毁&#xff0c;这个过程中创建和销毁都需要耗费大量资源&#xff0c;因此…

shell 条件测试详解

目录 shell条件测试 一&#xff0c;条件测试的基本语法 1&#xff0c;test 2&#xff0c;[ ] 3&#xff0c;[[ ]] 二&#xff0c;文件测试表达式 1&#xff0c;判断目录是否存在&#xff1a; 2&#xff0c;判断文件file1是否有写的权限&#xff0c;结果为有 3&#xf…

重学MySQL基础(一)

文章目录重学MySQL基础&#xff08;一&#xff09;MySQL 连接管理MySQL字符编码InnoDB 记录存储结构InnoDB 表的主键生成策略&#xff1a;InnoDB 数据页结构页目录页的效验和索引事务报错记录在MySQL中创建函数时出现这种错误恶补SQL语句SQL中的条件语句SQL中的字符串函数SQL中…

python调用go语言踩坑记录

目录 基本操作 1 在go文件中加注释&#xff0c;设置为导出方法,导出C依赖 2 导出so文件&#xff08;mac或者linux下只需要so&#xff09; 3 进行调用 报错记录 踩坑1 关于结构体 2 cannot use (_Cfunc_CString)("12345") (value of type *_Ctype_char) as ty…

spring中事务失效场景

文章目录spring中事务失效场景一、权限访问问题二、方法用final修饰三、无事务嵌套有事务的方法四、没有被spring管理五、设计的表不支持事务六、没有开启事务七、错误的事务传播八、自己捕获了异常九、手动抛出别的异常十、自定义回滚异常spring中事务失效场景 一、权限访问问…

软件研发管理经验总结 - 事务管理

软件研发管理经验总结 - 事务管理 相关系列文章 软件产品研发管理经验总结-管理细分 软件研发管理经验总结 - 事务管理 目录软件研发管理经验总结 - 事务管理一、概述二、事务管理过程1、制定开发计划2、启动会议3、阅读前一天的日报4、例会/早会5、调整计划6、协调资源7、日报…

LeetCode——2325. 解密消息

一、题目 给你字符串 key 和 message &#xff0c;分别表示一个加密密钥和一段加密消息。解密 message 的步骤如下&#xff1a; 使用 key 中 26 个英文小写字母第一次出现的顺序作为替换表中的字母 顺序 。 将替换表与普通英文字母表对齐&#xff0c;形成对照表。 按照对照表…

vue全家桶(三)前端路由

vue全家桶&#xff08;三&#xff09;前端路由1.路由的概念1.1路由1.2vue Router2.vue-router的基本使用步骤2.1基本使用步骤2.2路由重定向3.vue-router的嵌套路由用法3.1嵌套路由的用法4.vue-router动态路由匹配用法5.vue-router命名路由用法6.vue-router编程式导航用法6.1 页…

06 Sentinel控制台规则配置讲解 (2)

1、实时监控 监控接口的通过的QPS和拒绝的QPS 2、簇点链路 用来显示微服务的所监控的API 3、流控规则 流量控制&#xff08;flow control&#xff09;&#xff0c;其原理是监控应用流量的 QPS 或并发线程数等指标&#xff0c;当达到指定的阈值时对流量进行控制&#xff0c;以…

源于《C陷阱与缺陷》----研究程序死循环问题

本题来源于《C陷阱与缺陷》这本书&#xff0c;从本质上讲解程序死循环的原因&#xff0c;关键在于栈的空间使用方式。研究程序死循环的原因死循环的原因是什么呢&#xff1f;解决方法总结研究程序死循环的原因 题目1&#xff1a; 在VS2019 X86环境下测试&#xff1a; int mai…

Linux服务器怎么设置iptables防火墙?

当今&#xff0c;为避免香港服务器及其端口受到恶意入侵&#xff0c;保障香港服务器的安全&#xff0c;配置Linux服务器防火墙的重要性不言而喻。恒创科技将向您介绍如何在 CentOS、Ubuntu 和 Debian 服务器中安装和配置 iptables防火墙。iptables是一个简单的防火墙&#xff0…

测试工程师必备技能之编写测试用例

1. 必要性 &#x1f449; 指导测试工作&#xff0c;用例通过率是评估质量的基准 &#x1f449; 完善测试人员测试的整体思路&#xff0c;不出现漏测 ❗️ 避免背锅&#xff0c;线上出了问题防止开发甩锅给测试 2. 模板 企业中用例往往是每个人负责不同模块&#xff0c;再根据…