每日OJ题_01背包①_牛客DP41 【模板】01背包(滚动数组优化)

目录

牛客DP41 【模板】01背包

问题一解析

问题二解析

解析代码

滚动数组优化代码


牛客DP41 【模板】01背包

【模板】01背包_牛客题霸_牛客网

#include <iostream>
using namespace std;int main() {int a, b;while (cin >> a >> b) { // 注意 while 处理多个 casecout << a + b << endl;}
}
// 64 位输出请用 printf("%lld")

问题一解析

背包问题的状态表示非常经典,如果不知道怎么来的,可以先把它当成一个模板。

以某个位置为结尾,结合题目要求,定义一个状态表示:

dp[i][j] 表示:从前 i 个物品中挑选,总体积不超过 j ,所有的选法中,能挑选出来的最大价值。

状态转移方程:

线性 dp 状态转移方程分析方式,一般都是根据最后一步的状况,来分情况讨论:

  • 不选第 i 个物品:相当于就是去前 i - 1 个物品中挑选,并且总体积不超过 j 。此时 dp[i][j] = dp[i - 1][j] ;
  • 选择第 i 个物品:那么就只能去前 i - 1 个物品中,挑选总体积不超过 j - v[i] 的物品。此时 dp[i][j] = dp[i - 1][j - v[i]] + w[i] ; 。但是这种状态不一定存在,要判断 j >= v[i]。

综上,状态转移方程为: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - v[i]] + w[i]) ;


初始化、填表顺序、返回值:

        多加一行,方便初始化,此时仅需将第一行初始化为 0 即可。因为什么也不选,也能满足体积不小于 j 的情况,此时的价值为 0 。填表顺序从左往右,最后返回dp[n][V] ; 


问题二解析

        第二问仅需微调一下 dp 过程的五步即可。 因为有可能凑不齐 j 体积的物品,因此把不合法的状态设置为 -1 。

以某个位置为结尾,结合题目要求,定义一个状态表示:

dp[i][j] 表示:从前 i 个物品中挑选,总体积正好等于 j ,所有的选法中,能挑选出来的最大价值。

状态转移方程:

线性 dp 状态转移方程分析方式,一般都是根据最后一步的状况,来分情况讨论:

  • 不选第 i 个物品:相当于就是去前 i - 1 个物品中挑选,并且总体积不超过 j 。此时 dp[i][j] = dp[i - 1][j] ;
  • 选择第 i 个物品:那么就只能去前 i - 1 个物品中,挑选总体积不超过 j - v[i] 的物品。此时 dp[i][j] = dp[i - 1][j - v[i]] + w[i] ; 。但是这种状态不一定存在,不仅要判断 j >= v[i] 还要判断 dp[i - 1][j - v[i]] 表示的情况是否存在,也就是 dp[i - 1][j - v[i]] != -1 。

综上,状态转移方程为: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - v[i]] + w[i]) ;


初始化、填表顺序、返回值:

        多加一行,方便初始化,第一行第一个格子为 0 ,因为正好能凑齐体积为 0 的背包,但是第一行第一个格子后面都是 -1 ,因为没有物品,无法满足体积大于 0 的情况。第一列全为0。

填表顺序从左往右,最后返回dp[n][V] ; 


解析代码

#include <iostream>
#include <cstring>using namespace std;const int N = 1010; // OJ定义成全局方便,且空间不会轻易溢出
int n, V, v[N], w[N];
int dp[N][N];int main()
{cin >> n >> V;for (int i = 1; i <= n; ++i) // 从1开始读数据{cin >> v[i] >> w[i];}for(int i = 1; i <= n; ++i){for(int j = 0; j <= V; ++j){dp[i][j] = dp[i - 1][j];if(j >= v[i])dp[i][j] = max(dp[i - 1][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 = 0; 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 - 1][j], dp[i - 1][j - v[i]] + w[i]);}}cout << (dp[n][V] == -1 ? 0 : dp[n][V]) << endl;return 0;
}


滚动数组优化代码

背包问题基本上都是利用滚动数组来做空间上的优化:(时间也有常数的优化)

  1. 利用滚动数组优化。
  2. 直接在原始代码上修改。

        第i行元素只依赖于第i-1行元素。理论上,只需要保持两行元素,所以只需两个数组交替滚动,就能完成dp数组的填充。因此空间复杂度从O(N^2) 变为O(N)。

        这里还可以直接用一个数组来进行优化:从前往后去更新数组,dp[j - v[ i ]]肯定不比dp[ j ]的值大,而改了前面,后面的更新就会用到前面更新的数据,而本来应该使用原二维数组 i - 1行的数据,也就是更新数据之前的,因此可以巧妙地从后往前遍历,这样就可以避免用到更新后的数据。

在01背包问题中,优化的结果为:

  1. 删掉所有的横坐标。
  2. 修改一下 j 的遍历顺序。

(滚动数组优化代码只需能在原代码上修改就行,不用考虑什么状态表示)

#include <iostream>
#include <cstring>using namespace std;const int N = 1010; // OJ定义成全局方便,且空间不会轻易溢出
int n, V, v[N], w[N];
// int dp[N][N];
int dp[N]; // 滚动数组优化,把所有dp表左边一维坐标删掉,修改遍历顺序int main()
{cin >> n >> V;for (int i = 1; i <= n; ++i) // 从1开始读数据{cin >> v[i] >> w[i];}for(int i = 1; i <= n; ++i){for(int j = V; j >= v[i]; --j) // 滚动数组优化{dp[j] = dp[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;
}

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

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

相关文章

软件杯 深度学习人体语义分割在弹幕防遮挡上的实现 - python

文章目录 1 前言1 课题背景2 技术原理和方法2.1基本原理2.2 技术选型和方法 3 实例分割4 实现效果5 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习人体语义分割在弹幕防遮挡上的应用 该项目较为新颖&#xff0c;适合作为竞…

二叉树学习

树 树是n个结点的有限集合&#xff0c;当n0时为空树&#xff0c;在任意一颗非空的树中&#xff0c;有且只有一个特定的称为根的结点&#xff0c;当n>1时&#xff0c;其余结点又可以分为m个不相交的有限集&#xff0c;其中每一个集合又是一棵树&#xff0c;并且称为根的子树…

【Java探索之旅】从输入输出到猜数字游戏

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; Java编程秘籍 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言一、输入输出1.1 输出到控制台1.2 从键盘输入 二、猜数字游戏2.1 所需知识&#xff1a…

《猎灵online》游戏完整源码(源码+客户端+服务端+文档+工具),云盘下载

《猎灵》是一款由国内知名开发运营开发的大型3D魔幻网游&#xff0c;《猎灵》研发团队突破诸多瓶颈&#xff0c;首创“全自由无限制PK”&#xff0c;让玩家拒绝无意义等待&#xff0c;自由作战不受任何束缚&#xff0c;真正的实现想战就战&#xff0c;游戏创建了六界神魔乱斗的…

Amazon SageMaker:让机器学习变得更简单、更强大

授权说明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 亚马逊云科技开发者社区, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道。 前言&#xff1a; 在大数据时代的浪潮中&#xff0c;数据不再只是…

Python神器!WEB自动化测试集成工具 DrissionPage

案例 跟踪商品价格&#xff0c;降价自动推送消息到微信 咱买不起还等不起吗&#xff1f; from DrissionPage import * import re from time import sleep import csv import os import datetime#写入时间p MixPage() p.get(http://xxxxxxx) #快快买网址 p.to_iframe(iframe…

云服务器centos提示 Cannot prepare internal mirrorlist: No URLs in mirrorlist的解决办法

yum update -y CentOS-8 - AppStream 118 B/s | 38 B 00:00 Error: Failed to download metadata for repo AppStream: Cannot prepare internal mirrorlist: No URLs in mirrorlist 执行下面的命令就可…

CSS特效---纯CSS实现点击切换按钮

1、演示 2、一切尽在代码中 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><meta name"viewport" content"w…

HashMap的常见问题

Entry中的hash属性为什么不直接使用key的hashCode()返回值呢&#xff1f; 不管是JDK1.7还是JDK1.8中&#xff0c;都不是直接用key的hashCode值直接与table.length-1计算求下标的&#xff0c;而是先对key的hashCode值进行了一个运算&#xff0c;JDK1.7和JDK1.8关于hash()的实现…

c++ 指针总结

概述 内存地址 在计算机内存中&#xff0c;每个存储单元都有一个唯一的地址(内存编号)。通俗理解&#xff0c;内存就是房间&#xff0c;地址就是门牌号 指针和指针变量 指针&#xff08;Pointer&#xff09;是一种特殊的变量类型&#xff0c;它用于存储内存地址。指针的实质…

算力租赁费用包括哪些

相比于企业自购设备、自建机房、自己运营&#xff0c;服务器租赁是绝大数企业的首先&#xff0c;租赁服务器从一定程度上解决了企业资金预算不足、AI芯片难买的局面。 随着文生视频大模型Sora、大语言模型Grok-1的相继出现&#xff0c;对高新能算力资源和服务的需求不断提高&a…

暴力枚举法

虽然暴力枚举法有时候效率低&#xff0c;时间复杂度高&#xff0c;但是在面对小规模数据集的时候&#xff0c;暴力枚举法往往是很好的思维利器。 B: 01 串的熵&#xff08;5分&#xff09; 问题描述 #include <iostream> #include <cmath> #include <algorithm…

什么是云HIS?云HIS的优点是什么?云HIS适用于什么医院?

什么是云HIS&#xff1f;云HIS的优点是什么&#xff1f;云HIS适用于什么医院&#xff1f; 一、什么是云HIS&#xff1f; 云HIS系统是一个运用云计算、大数据、物联网等新兴信息技术的业务和技术平台。它旨在按照现代医疗卫生管理要求&#xff0c;以数字化形式提供医疗卫生行业…

Mybatis generate xml 没有被覆盖

添加插件即可 <plugin type"org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin"/>

epic免费游戏在哪里领 epic免费游戏怎么领取 图文教程一看就会

Epic Games是一家位于美国北卡罗来纳州卡里的视频游戏和软件开发商&#xff0c;由Tim Sweeney于1991年创立。该公司最著名的作品包括《堡垒之夜》和虚幻引擎&#xff0c;后者是一种广泛用于游戏开发的商用游戏引擎。Epic Games在2020年和2024年分别与索尼和迪士尼达成财务合作及…

ARM架构麒麟操作系统安装配置Mariadb数据库

、安装配置JDK (1)检查机器是否已安装JDK 执行 java -version命令查看机器是否安装JDK,一般麒麟操作系统默认安装openjdk 1.8。 (2)安装指定版本JDK 如果麒麟操作系统默认安装的openjdk 1.8不符合需求的话,可以卸载机器安装的openjdk 1.8并按需安装所需的openjdk版本…

#esp8266模块通过AT指令获取网络时间(苏宁时间)

一、IDE&#xff1a;keil、cubemx、Arduino......... 二、记录&#xff1a; 1.依次发送以下指令&#xff08;发送新行&#xff09; AT ATCWMODE1 ATCWDHCP1,1 ATCWJAP"Redmi K40 Gaming","87654321" ATCIPSTART"TCP","quan.suning.com&quo…

Leetcode110_平衡二叉树

1.leetcode原题链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 2.题目描述 给定一个二叉树&#xff0c;判断它是否是 平衡二叉树 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;true示例 2&#xff1a; 输入&#xff1a;…

RabbbitMQ

初识MQ 同步通讯和异步通讯 什么是同步通讯呢&#xff1f;举个例子&#xff0c;你认识了一个小姐姐&#xff0c;聊的很火热&#xff0c;于是你们慢慢开始打电话&#xff0c;视频聊天&#xff0c;这种方式就成为同步通讯&#xff0c;那什么是一部通讯呢&#xff0c;同样的&…

【性能测试】接口测试各知识第3篇:Jmeter 基本使用流程,学习目标【附代码文档】

接口测试完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;接口测试&#xff0c;学习目标学习目标,2. 接口测试课程大纲,3. 接口学完样品,4. 学完课程,学到什么,5. 参考:,1. 理解接口的概念。学习目标&#xff0c;RESTFUL1. 理解接口的概念,2.什么是接口测试…