0/1背包
0/1背包
背包问题是DP最经典的类型之一,而0/1背包是最经典最基础的背包问题。
背包体积为 V V V, n n n种物品,每种物品只有1个,第 i i i种物品对应体积为 c i c_i ci,价值为 w i w_i wi,怎样装填能使背包总价值最大?
由于每件物品只有选(0)与不选(1)两种情况,故称为0/1背包问题。
分析:闫氏DP分析法
- 状态表示
- 集合:定义数组 d p [ i ] [ j ] dp[i][j] dp[i][j],表示当前选取方案的价值。第 i i i行表示只考虑前 i i i个物品的放置情况, j j j表示当前选取体积不超过 j j j的方案集合。
- 属性: M a x Max Max
- 初始化:对于最值问题, d p [ i ] [ 0 ] = f [ 0 ] [ j ] = 0 dp[i][0]=f[0][j]=0 dp[i][0]=f[0][j]=0
- 状态计算: d p [ i ] [ j ] dp[i][j] dp[i][j]:对于第 i i i种物品:
- 不可选第 i i i种物品: v < c [ i ] v<c[i] v<c[i],无法装入背包,背包剩余容积不变。集合状态仍为 [ 1 , i − 1 ] [1,i-1] [1,i−1],直接继承自第 i − 1 i-1 i−1种物品且背包容积仍为 j j j方案的价值。 d p [ i ] [ j ] = d p [ i − 1 ] [ j ] dp[i][j]=dp[i-1][j] dp[i][j]=dp[i−1][j]
- 可选第 i i i种物品:
- 不选第 i i i种物品:若选第 i i i种物品无法保证最优解,则不选,背包剩余容积不变。集合状态仍为 [ 1 , i − 1 ] [1,i-1] [1,i−1],直接继承自第 i − 1 i-1 i−1个物品且背包容积仍为 j j j方案的价值。 d p [ i ] [ j ] = d p [ i − 1 ] [ j ] dp[i][j]=dp[i-1][j] dp[i][j]=dp[i−1][j]
- 选第 i i i种物品:选第 i i i种物品可能导致产生最优解,则选。集合状态仍为 [ 1 , i − 1 ] [1,i-1] [1,i−1],因为0/1背包要求每种物品只能选一次,故继承自第 i − 1 i-1 i−1种物品且背包容积减少 c [ i ] c[i] c[i]方案的价值,并加 w [ i ] w[i] w[i]。 d p [ i ] [ j ] = d p [ i − 1 ] [ j − c [ i ] ] + w [ i ] dp[i][j]=dp[i-1][j-c[i]]+w[i] dp[i][j]=dp[i−1][j−c[i]]+w[i]
- 状态转移方程式: d p [ i ] [ j ] = m a x ( d p [ i − 1 ] [ j ] , d p [ i − 1 ] [ j − c [ i ] ] + w [ i ] ) dp[i][j]=max(dp[i-1][j],dp[i-1][j-c[i]]+w[i]) dp[i][j]=max(dp[i−1][j],dp[i−1][j−c[i]]+w[i])
遍历顺序:物品和背包谁先遍历都可以,根据状态转移方程式,dp数组的当前位置只与正上方和左上方有关,无论哪种遍历顺序,都可以确保在到达当前位置之前,正上方和左上方都有值。
初始化:
void init(){for(int i=0;i<=n;i++) dp[i][0]=0;for(int i=0;i<=v;i++) dp[0][j]=0;
}
void dp(){for(int i=1;i<=n;i++)//遍历物品for(int j=1;j<=v;j++)//遍历背包if(c[i]<=j) dp[i][j]=max(dp[i-1][j],dp[i-1][j-c[i]]+w[i]);else dp[i][j]=dp[i-1][j];
}
时间复杂度O( n v nv nv),空间复杂度O( n v nv nv)
DP表
滚动数组
DP问题的空间复杂度一般很高,可采用滚动数组方式对空间复杂度进行优化。
滚动数组原理是基于DP的无后效性,第 i i i行只与 i − 1 i-1 i−1行有关,至于 i − 1 i-1 i−1行之前的数据第 i i i行无需关注,因此在DP过程中实际上只有两行在进行工作,故可极大程度优化空间复杂度。
注意,滚动数组使中间信息丢失,若需要输出背包具体方案,则不能采用滚动数组。
交替滚动
思路:定义 d p [ 2 ] [ v ] dp[2][v] dp[2][v],当前工作指针 w o r k work work和上次工作指针 o l d old old,使用 d p [ w o r k ] [ v ] dp[work][v] dp[work][v]和 d p [ o l d ] [ v ] dp[old][v] dp[old][v]进行交替滚动,每次滚动后交换工作指针即可,思路简单
int dp[2][v];
void dp(){int work=0,old=1;for(int i=1;i<=n;i++){swap(work,old);//交换工作指针而非交换数组元素for(int j=1;j<=v;j++)if(c[i]<=j) dp[work][j]=max(dp[old][j],dp[old][j-c[i]]+w[i]);else dp[work][j]=dp[old][j];}
}
自我滚动
思路:由状态转移方程式可知,当前元素只继承自上一行正上方( d p [ i − 1 ] [ j ] dp[i-1][j] dp[i−1][j])或上一行左上方( d p [ i − 1 ] [ j − 1 ] dp[i-1][j-1] dp[i−1][j−1]),因此逆序遍历背包容量进行更新,可将数组压至一维。
必须对背包进行逆序更新,这样是为了满足0/1背包每种物品只能选1个的性质,若顺序遍历则可能会对1种物品选多次,此时则为完全背包,且此错误必然会在选第1种物品时就发生。
自我滚动的0/1背包只可先遍历物品再遍历背包,不可颠倒(完全背包可颠倒)。

int dp[v];
void dp(){for(int i=1;i<=n;i++){//顺序遍历物品for(int j=v;j>=c[i];j--)//逆序遍历背包,装不下的不用管dp[j]=max(dp[j],dp[j-c[i]]+w[i]);}
}
输出具体方案
思路:定义标记数组,从 d p dp dp终点开始步步向上回溯,根据0/1背包状态转移方程式 p [ i ] [ j ] = m a x ( d p [ i − 1 ] [ j ] , d p [ i − 1 ] [ j − c [ i ] ] + w [ i ] ) p[i][j]=max(dp[i-1][j],dp[i-1][j-c[i]]+w[i]) p[i][j]=max(dp[i−1][j],dp[i−1][j−c[i]]+w[i])可知,判断 d p [ i ] [ j ] dp[i][j] dp[i][j]与 d p [ i − 1 ] [ j ] dp[i-1][j] dp[i−1][j]和 d p [ i − 1 ] [ j − c [ i ] ] + w [ i ] dp[i-1][j-c[i]]+w[i] dp[i−1][j−c[i]]+w[i]关系即可判断第 i i i个物品是否已装,最后输出标记数组。
注:求解具体方案仅适用于非滚动数组,因为滚动过程会将中间状态信息丢失。
extern int dp[MAX][MAX],i,j;//i,j:dp终点
bool f[MAX];
void print(){for(;i>=1;i--){if(j>=c[i]&&dp[i][j]==dp[i-1][j-c[i]+w[i]]){//说明第i个物品已选f[i]=1;j-=c[i];}}for(int k=1;k<=n;k++) if(f[k]) cout<<k<<' ';
}
相关文章:
0/1背包
0/1背包 背包问题是DP最经典的类型之一,而0/1背包是最经典最基础的背包问题。 背包体积为 V V V, n n n种物品,每种物品只有1个,第 i i i种物品对应体积为 c i c_i ci,价值为 w i w_i wi,怎样装填能使…...
Linux的进程和权限的基本命令
目录 基本命令 man find date cal du ln exit grep 基本命令-帮助查询: wc cat more less head tail echo alias unalias 基本命令-进程管理: ps kill top 操作系统负载查看 用户分类: 程序用户 普通用户&#x…...
鼠标录制工具怎么挑选?9款电脑鼠标录制工具分享(2024)
你知道鼠标录制工具吗?鼠标录制工具通过记录和回放用户的操作,帮助自动化重复性任务,提高工作效率和精确性。它可以帮助用户简化很多繁琐的操作步骤,非常适合运用在电脑自动化任务、游戏自动化中,给大家整理了2024年9款…...
C1W4.LAB.Vector manipulation+Hash functions and multiplanes
理论课:C1W4.Machine Translation and Document Search 文章目录 Python 中的矢量操作Transforming vectorsExample 1Example 2 Frobenius Norm Hash functions and multiplanesBasic Hash tablesPlanesHash Function with multiple planesRandom PlanesDocument v…...
YOLOv8改进 | 检测头 | 融合渐进特征金字塔的检测头【AFPN4】
秋招面试专栏推荐 :深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡 专栏目录 :《YOLOv8改进有效…...
数据采集监控平台:挖掘数据价值 高效高速生产!
在当今数字化的时代,数据已成为企业非常宝贵的资产之一。然而,要充分发挥数据的潜力,离不开一个强大的数据采集监控平台,尤其是生产制造行业。它不仅是数据的收集者,更是洞察生产的智慧之眼,高效高速处理产…...
【算法笔记自学】第 9 章 提高篇(3)——数据结构专题(2)
9.1树与二叉树 #include <cstdio>int main() {int n, m;scanf("%d%d", &n, &m);printf(n m 1 ? "Yes" : "No");return 0; } 9.2二叉树的遍历 #include <cstdio> #include <vector> using namespace std;const int…...
Objective-C 中字符串的保存位置
在 Objective-C 中,字符串常量和动态创建的字符串(例如通过 stringWithFormat:、initWithString: 等方法创建的字符串)在内存中保存的位置一样么 ? 在 Objective-C 中,字符串常量和动态创建的字符串在内存中的保存位置…...
git 想要创建一个新的本地分支并检出远程分支的内容
如果你想要创建一个新的本地分支并检出远程分支的内容: git checkout -b feature-branch origin/feature-branch feature-branch 是你在本地创建的新分支名,origin/feature-branch 是远程分支的引用。 根据你检出的远程分支的名字而定 不知道名称的时…...
C语言学习笔记[24]:循环语句while②
getchar()的使用场景 int main() {char password[20] {0};printf("请输入密码:");//输入 123456 后回车scanf("%s", passwoed);//数组名本身就是数组地址printf("请确认密码:Y/N");int ch getchar();if(Y ch)printf(&…...
安全运营概述
安全运营概述 概述安全运营的工作对内安全运营工作对外安全运营工作品牌建设 概述 安全是一个过程,安全是靠运营出来的,公司会不断的有新业务的变更,新产品的发布,新版本的升级,技术架构的升级,底层系统的…...
spring-cloud和spring-cloud-alibaba的关系
首先Spring Cloud 是什么? Spring Cloud是一系列框架的有序集合,它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发。Spring Cloud提供了微服务架构开发所需的多种组件和工具,如服务发现注册、配置中心、消息总线、负载均…...
持续集成06--Jenkins构建触发器
前言 在持续集成(CI)的实践中,构建触发器是自动化流程中不可或缺的一环。它决定了何时启动构建过程,从而确保代码变更能够及时地得到验证和反馈。Jenkins,作为业界领先的CI/CD工具,提供了多种构建触发器选项…...
根据视图矩阵, 恢复相机的世界空间的位置
根据视图矩阵, 恢复相机的世界空间的位置 一、方法1 glsl 实现: // 从本地局部坐标系(相机空间) 到 世界空间的旋转变换 mat3 getLocal2WorldRotation() {mat3 world2localRotation mat3(viewMatrix[0].xyz,viewMatrix[1].xyz,viewMatrix[2].xyz);return inverse(world2loca…...
使用pytest-playwright截图和录制视频并添加到Allure报告
一、依赖环境 python, version==3.9.5 pytest-playwright, version==0.5.1 allure-pytest, version==2.13.5 pytest, version==6.2.5 allure, version==2.22.0pytest-playwright支持如下命令行参数: Playwright:--browser={chromium,firefox,webkit}Browser engine which …...
pytorch GPU cuda 使用 报错 整理
GPU 使用、报错整理 1. 使用指定GPU(单卡)1.1 方法1:os.environ[CUDA_VISIBLE_DEVICES]1.2 方法2:torch.device(cuda:2)1.3 报错1:RuntimeError: CUDA error: invalid device ordinal CUDA kernel errors might be asy…...
python + Pytest + requests 的接口自动化步骤
pythonpytestrequestallureyaml接口自动化测试项目实战 开发环境准备 1. jdk 下载 Java官网下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 安装: https://blog.csdn.net/VA_AV/article/details/138…...
基于若依的ruoyi-nbcio流程管理系统修正自定义业务表单的回写bug
更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码: https://gitee.com/nbacheng/ruoyi-nbcio 演示地址:RuoYi-Nbcio后台管理系统 http://218.75.87.38:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码: h…...
GD32 MCU上电跌落导致启动异常如何解决
大家是否碰到过MCU上电过程中存在电源波动或者电压跌落导致MCU启动异常的问题?本视频将会为大家讲解可能的原因以及解决方法: GD32 MCU上下电复位波形如下图所示,上电过程中如果存在吃电的模块,比如wifi模块/4G模块/开启某块电路…...
安防视频监控/视频汇聚EasyCVR平台浏览器http可以播放,https不能播放,如何解决?
安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台基于云边端一体化架构,兼容性强、支持多协议接入,包括国标GB/T 28181协议、部标JT808、GA/T 1400协议、RTMP、RTSP/Onvif协议、海康Ehome、海康SDK、大华SDK、华为SDK、宇视SDK、乐橙SDK、萤石云SD…...
106. 如何禁用牧场主日志的注释收集
Environment 环境 SUSE Rancher Prime - All versions SUSE Rancher Prime - 所有版本 Rancher-logging-105.3.x Procedure 程序 There could be situations where users might want to disable annotation collection with rancher-logging in order to reduce the amount o…...
当00后测试员给CEO系统提了487个缺陷后
在软件测试领域,一个年轻测试员的行动往往能引发行业深思。故事始于一家科技公司新上线的“CEO决策支持系统”——一个旨在为高管提供实时数据分析和战略建议的核心平台。项目团队信心满满地推进上线,却未料到一位00后测试员小陈的介入,彻底改…...
管道应力理论(应用)
本文仅对管道应力涉及的理论知识(偏向于应用)进行简单介绍。管道应力:对管道应力校核是为了防止管壁内应力过大对管道造成破坏,不同的荷载引起不同类型的应力,在实际工程应用中,一般分为三种:一…...
Klipper温度曲线优化终极指南:三步解决95%打印质量问题
Klipper温度曲线优化终极指南:三步解决95%打印质量问题 【免费下载链接】klipper Klipper is a 3d-printer firmware 项目地址: https://gitcode.com/GitHub_Trending/kl/klipper 你是否曾为PLA打印翘边、ABS层间开裂或PETG拉丝问题而烦恼?这些问…...
ai如何助力github项目管理:从智能生成readme到自动编排changelog
今天在准备一个AI图像识别工具的开源项目时,突然意识到GitHub仓库初始化其实可以很智能。以前手动创建目录、写README的日子太费时间了,现在用AI辅助开发,整个过程流畅得像有个技术助理在身边。下面记录下我的实践过程: 智能仓库…...
避坑指南:YOLOv8+PaddleOCR车牌识别中,那些让你识别率暴跌的细节
避坑指南:YOLOv8PaddleOCR车牌识别中那些让你识别率暴跌的细节 车牌识别系统在智慧交通、安防监控等领域的应用越来越广泛,但很多工程师在部署YOLOv8PaddleOCR方案时,明明按照教程一步步操作,实际识别效果却远不如预期。本文将揭…...
数据安全与性能瓶颈困扰企业?湖南天硕SSD固态硬盘带来航天级稳定体验
在数字化转型加速的今天,企业数据量呈指数级增长,随之而来的数据安全风险与存储性能瓶颈已成为众多企业,尤其是对数据可靠性要求极高的B端用户(如企业采购负责人、技术总监)面临的共同挑战。传统存储方案在应对复杂业务…...
新手必看:详解cursor注册手机号填写步骤与前端实现
新手必看:详解cursor注册手机号填写步骤与前端实现 最近在帮几个编程新手朋友解决cursor注册时遇到的手机号填写问题,发现很多细节容易被忽略。于是我用InsCode(快马)平台快速搭建了一个演示项目,把整个过程拆解成可视化的步骤,顺…...
98. 未使用的机器配置(rke-machine-config.cattle.io)在 Rancher v2.10+ 中会自动清理
Environment 环境 SUSE Rancher Prime v2.10.x till v2.11.x SUSE Rancher Prime v2.10.x 到 v2.11.xRKE2VMware vSphereAWS EC2 Situation 地理位置After upgrading to Rancher v2.10, VmwarevsphereConfigs created via Terraform (rancher2_machine_config_v2) are automa…...
如何高效使用猫抓cat-catch:5个关键技巧完全指南
如何高效使用猫抓cat-catch:5个关键技巧完全指南 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 你是否经常遇到这样的情况:…...
