【OJ】动规练习七之【模板】01背包

个人主页 : zxctscl
如有转载请先通知

DP41 【模板】01背包

  • 1. DP41 【模板】01背包
  • 2. 分析
  • 3. 代码
  • 4. 优化
  • 5. 优化后代码

1. DP41 【模板】01背包

在这里插入图片描述

2. 分析

一、题目解析:
来看一下例1,3代表有三个物品,5代表能够容纳的体积。第一行要求中并没有说把背包全部装满,选择价值最大的就行,而第二行输出要求的是装满时候的价值。
在体积是5条件下,第一种可以选1号物品和3号物品,它们价值就是10+4=14;第二种可以选择2号和3号,它们价值就是5+4=9,第一行输出没有要求背包装满,所以选择第一种方式就行。
第二行输出是背包恰好装满的情况,就选择第二种情况。
在这里插入图片描述
而输出背包必须装满的情况可能是不存在的,就像例2:
给的三个物品体积凑不出来体积为8的情况。
在这里插入图片描述

二、算法原理:
(1)先来做第一行返回值:

  1. 状态表示
    以某一个位置为结尾
    如果用dp[i]来表示从前i个物品中选择,在所有选择中的最大价值,但是还得考虑体积的大小。所以这里的状态表示是:
    dp[i][j]:从从前i个物品中选择,总体积不超过j的所有选择中,能挑出来的最大价值。

  2. 状态转移方程
    根据最后一步的状况,分情况讨论。
    第一种情况:不选择i物品,那么就是在i-1里面选择,并且体积也依旧小于j,所以就是dp[i-1][j]
    在这里插入图片描述

第二种情况:选择i物品,那么必须有w[i],实现的价值最大,就得从i-1里面挑价值最大的出来,并且此时体积要改变,所以到这里的体积必须能够装下v[i],到i-1位置体积就必须小于j-v[i],所以这里的状态表示就是w[i]+dp[i-1][j-v[i]]
然后求这两种情况下的最大值就可以了。

  1. 初始化
    dp表从1开始计数,就多了一行和一列。要保证第一行和第一列填表正确,物品从0中选就是0,体积从0中挑还是0,所以初始化为0就行。

  2. 填表顺序
    它依赖它的上一行位置,i-1表示的是上一行,从上往下

  3. 返回值

返回dp[n][v]
(2)先来做第一行返回值:

  1. 状态表示
    只需要v的位置正好等于j就行
    dp[i][j]:从从前i个物品中选择,总体积正好等于j的所有选择中,能挑出来的最大价值。

  2. 状态转移方程
    第一种情况:不选择i物品,那么就是在i-1里面选择,并且体积也依旧小于j,所以就是dp[i-1][j],但是这里j可能凑不到总体积,就用一个dp[i][j]=-1来表示这样的情况,所以得先判断dp[i][j]是不是等于-1,所以这种情况就不选择。

第二种情况:选择i物品,那么必须有w[i],实现的价值最大,就得从i-1里面挑价值最大的出来,并且此时体积要改变,所以到这里的体积必须能够装下v[i],到i-1位置体积就必须小于j-v[i],但是这里必须判断dp[i][j]是不是等于-1,所以这里的状态表示就是dp[i][j]不是等于-1情况下w[i]+dp[i-1][j-v[i]]

  1. 初始化
    第一个位置没有物品直接物品和体积都是0,第一行[0,1]位置没有物品,想要凑成体积是1是不可能的,所以第一行剩下的位置就初始化为-1。第一列表示想要把体积正好凑成0,那么不选就是0,就初始化为0就行
    在这里插入图片描述

  2. 填表顺序
    从上往下

  3. 返回值
    先得判断一下dp[n][V]是不是等于-1,如果是就返回0,不是就返回dp[n][V]
    在这里插入图片描述

3. 代码

#include <cstring>
#include <iostream>using namespace std;
const int N = 1010;
int n, V, v[N], w[N];
int dp[N][N];int main() {cin >> n >> V;for (int i = 1; i <= n; i++)cin >> v[i] >> w[i];for (int i = 1; i <= n; i++) {for (int j = 1; j <= V; j++) {dp[i][j] = dp[i - 1][j];if (j >= v[i])dp[i][j] = max(dp[i][j], dp[i - 1][j - v[i]] + w[i]);}}cout << dp[n][V] << endl;//第二问memset(dp, 0, sizeof dp);for (int j = 1; j <= V; j++)dp[0][j] = -1;for (int i = 1; i <= n; i++) {for (int j = 1; j <= V; j++) {dp[i][j] = dp[i - 1][j];if (j >= v[i]&&dp[i-1][j-v[i]]!=-1) {dp[i][j] = max(dp[i][j], dp[i - 1][j - v[i]] + w[i]);}}}cout <<(dp[n][V]==-1?0:dp[n][V]) << endl;return 0;
}
// 64 位输出请用 printf("%lld")

4. 优化

  1. 利用滚动数组做空间上的优化
  2. 代码在原基础上修改即可

在填第i行的时候,仅想要i-1行就可以。
就是说要填第1行的数据就需要第0行的数据,第1行填完之后,第0行就没有用了,需要这一行变得有用,就把这一行滚动到第2行,然后利用第1行的值来填第2行,以此类推,就可以更新完这个dp表。
在这里插入图片描述
所有这里只需要用到数组就只用到一维。

遍历顺序要改为从右往左。

在这里插入图片描述

5. 优化后代码

删除所有横坐标,遍历顺序从右往左

#include <cstring>
#include <iostream>using namespace std;
const int N = 1010;
int n, V, v[N], w[N];
int dp[N];int main() {cin >> n >> V;for (int i = 1; i <= n; i++)cin >> v[i] >> w[i];for (int i = 1; i <= n; i++) {for (int j = V; j >=v[i]; j--) dp[j] = max(dp[j], dp[j - v[i]] + w[i]);}cout << dp[V] << endl;//第二问memset(dp, 0, sizeof dp);for (int j = 1; j <= V; j++)dp[j] = -1;for (int i = 1; i <= n; i++) {for (int j = V; j >=v[i]; j--) if(dp[j-v[i]]!=-1)dp[j] = max(dp[j], dp[j - v[i]] + w[i]);}cout <<(dp[V]==-1?0:dp[V]) << endl;return 0;
}
// 64 位输出请用 printf("%lld")

注意:

  1. 这些思路是可以套用到很多题目里面的。
  2. 不要去强行解释优化后代码的状态表示及状态表示方程。

有问题请指出,大家一起进步!!!

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

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

相关文章

1970-2021年全国区县级碳排放数据8

1970-2021年全国区县级碳排放数据 1、时间&#xff1a;1970-2021年 2、指标&#xff1a;2877个区县 3、来源&#xff1a;EDGAR 4、指标&#xff1a;二氧化碳排放量 5、样本量&#xff1a;14W 6、指标解释&#xff1a; 二氧化碳排放是一个生态环境专业术语&#xff0c;主…

【Python系列】读取 Excel 第一列数据并赋值到指定列

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

PyCharm远程链接AutoDL

AutoDL使用方法&#xff1a; Step1&#xff1a;确认您安装的PyCharm是社区版还是专业版&#xff0c;只有专业版才支持远程开发功能。 Step2&#xff1a;开机实例 复制自己实例的SSH指令&#xff0c;比如&#xff1a;ssh -p 38076 rootregion-1.autodl.com 在ssh -p 38076 roo…

二、计算机网络体系结构参考模型

一、分层结构 &#xff08;一&#xff09;为什么要分层&#xff1a; 发送文件/数据前要完成的工作&#xff1a; 1&#xff09;发起通信的计算机必须讲数据通信通路进行激活 2&#xff09;要告诉网络如何识别目的主机 3&#xff09;发起通信的计算机要查明目的主机是否开机、并且…

先登杯·14天创作挑战营·第④期~ 等你来战!

文章目录 ⭐️ 活动介绍⭐️ 活动详情⭐️ 活动奖品⭐️ 活动流程​⭐️ 评审规则⭐️ 报名&投稿注意事项⭐️ 活动组织 ​ 活动报名入口&#xff1a;https://bbs.csdn.net/topics/618374514 本次活动与官方活动及其他博主的创作型活动并不冲突&#xff01; ​ ​ ⭐️…

Go语言hash/fnv应用实战:技巧、示例与最佳实践

Go语言hash/fnv应用实战&#xff1a;技巧、示例与最佳实践 引言hash/fnv概览使用hash/fnv的初步步骤导入hash/fnv库创建哈希器实例 hash/fnv在实际开发中的应用生成唯一标识符数据分片与负载均衡快速查找 高级技巧和最佳实践避免哈希碰撞动态调整哈希表大小利用sync.Pool优化哈…

STM32之HAL开发——不同系列SPI功能对比(附STM32Cube配置)

不同系列STM32——SPI框图 F1系列框图 F4系列框图 TI模式时序图特性 F7系列框图 H7系列框图 注意&#xff1a;F7系列以及H7系列支持Quad-SPI模式&#xff0c;可以连接单&#xff0c;双或者四条数据线的Flash存储介质。 SPI——Cube配置流程 RCC时钟源配置 SYS系统调试模式配…

1.JavaEE进阶篇 - 为什么要学习SpringBoot呢?

文章目录 1.为什么要学框架&#xff1f;2.框架的优点展示(SpringBoot VS Servlet)2.1 Servlet 项⽬开发2.1.1 创建项⽬2.1.2 添加引⽤2.1.3 添加业务代码2.1.4 运⾏项⽬(配置tomcat)2.1.5 Maven配置2.1.5.1修改本地Maven仓库地址2.1.5.2 配置settings.xml文件2.1.5.3项目 本地仓…

通用开发技能系列:Git

云原生学习路线导航页&#xff08;持续更新中&#xff09; 本文是 通用开发技能系列 文章&#xff0c;主要对编程通用技能Git进行学习 1.为什么使用版本控制系统 版本控制系统可以解决的问题 代码备份很重要版本控制很重要协同工作很重要责任追溯很重要 常见的版本控制系统 Gi…

网站建设 之 发布ios

首先将forceDev改为false 然后执行npm run build:ios 然后用xocode安装到手机上进行测试 ##Version&#xff08;应用程序发布版本号&#xff09; 对应的就是CFBundleShortVersionString。该版本的版本号是三个时期分隔的整数组成的字符串&#xff1a; 第一个整数代表重大修…

升级一下电脑,CPU换I5-14600K,主板换华硕B760M

刚给自己电脑升级了一下&#xff0c;CPU从 AMD R5 5600X 换成 Intel I5-14600K&#xff0c;主板换成了华硕的 TUF GAMING B760M-PLUS WIFI D4。 因为我现有的两根内存是DDR4的&#xff0c;所有我选了个支持DDR4内存的主板。 我发现用AMD处理器时将系统从Win10升级到Win11后变…

十四款大型语言模型在《街头霸王III》中一决雌雄

上周在旧金山举办的Mistral AI黑客马拉松上&#xff0c;开发出了一款基于经典街机游戏《街头霸王III》的人工智能&#xff08;AI&#xff09;基准测试。这款名为“AI Street Fighter III”的开源基准测试由Stan Girard和Quivr Brain开发&#xff0c;游戏在模拟器中运行&#xf…

PostgreSQL 文章下架 与 热更新和填充可以提升数据库性能

开头还是介绍一下群&#xff0c;如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, Oceanbase, Sql Server等有问题&#xff0c;有需求都可以加群群内有各大数据库行业大咖&#xff0c;CTO&#xff0c;可以解决你的问题。加群请联系 liuaustin3 &#xff0c;&#xff08;…

【51单片机入门记录】A/D、D/A转换器PCF859应用

目录 一、IIC初始化代码 二、开发板电路图 三、PCF8591读/写字节操作流程及相关函数 &#xff08;1&#xff09;PCF8591&#xff08;AD&#xff09;读操作流程及代码 &#xff08;2&#xff09;PCF8591&#xff08;AD&#xff09;写操作流程及代码 四、应用示例-显示电压…

论文笔记:UNDERSTANDING PROMPT ENGINEERINGMAY NOT REQUIRE RETHINKING GENERALIZATION

ICLR 2024 reviewer评分 6888 1 intro zero-shot prompt 在视觉-语言模型中&#xff0c;已经取得了令人印象深刻的表现 这一成功呈现出一个看似令人惊讶的观察&#xff1a;这些方法相对不太受过拟合的影响 即当一个提示被手动工程化以在给定训练集上达到低错误率时&#xff0…

学习心得1

这时我第一次更学习心得&#xff01;不足的在评论区指教。 首先先来分享一下&#xff0c;刷一维数组题目的方法。 仔细读题&#xff0c;不会做的题目先完成输入输出。不要干等着着急&#xff0c;就跳到下一题。如果使用的时oj&#xff0c;那就没有题解但是使用洛谷、LeetCood…

Prometheus+grafana监控nacos和spring-boot服务(增加自定义指标)(七)

前面记录了项目中常用的各种中间件的指标采集器的用法及搭建方式 &#xff0c; 由于所有组件写一篇幅过长&#xff0c;所以每个组件分一篇方便查看&#xff0c;前六篇链接如下 Prometheusgrafana环境搭建方法及流程两种方式(docker和源码包)(一)-CSDN博客 Prometheusgrafana…

LeetCode - 边积分最高的节点

2374. 边积分最高的节点 这是一个有向图&#xff0c;且每个节点都只有一条出边&#xff0c;指向0的边有1&#xff0c;2&#xff0c;3&#xff0c;4 10&#xff0c; 指向7的有5&#xff0c;6 11. 我们只需要一次遍历就可以解决&#xff0c;先搞一张哈希表&#xff0c;k存节点…

解决VScode中matplotlib图像中文显示问题

一、更改配置文件 参考这个文件路径找到自己Python环境下的matplotlibrc文件并用记事本打开。 用ctrl F寻找下面的这两行并将前面的#删除&#xff0c;保存并退出。 font.family: sans-serif font.serif: DejaVu Serif, Bitstream Vera Serif, Computer Modern Roman, N…

Day31|贪心算法part01:理论基础、455.分发饼干、376. 摆动序列、53. 最大子序和

理论基础 记得贪心没有规律即可&#xff01;解不出来就看题解。 455. 分发饼干 先把学生和饼干都排序&#xff08;Arrays.sort只能升序&#xff09;&#xff0c;然后都从后往前遍历&#xff0c;把最大的饼干给需求最大的孩子&#xff08;贪心&#xff09; class Solution {…