当前位置: 首页 > news >正文

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分析法

闫氏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,i1],直接继承自第 i − 1 i-1 i1种物品且背包容积仍为 j j j方案的价值。 d p [ i ] [ j ] = d p [ i − 1 ] [ j ] dp[i][j]=dp[i-1][j] dp[i][j]=dp[i1][j]
    • 可选第 i i i种物品:
      • 不选第 i i i种物品:若选第 i i i种物品无法保证最优解,则不选,背包剩余容积不变。集合状态仍为 [ 1 , i − 1 ] [1,i-1] [1,i1],直接继承自第 i − 1 i-1 i1个物品且背包容积仍为 j j j方案的价值。 d p [ i ] [ j ] = d p [ i − 1 ] [ j ] dp[i][j]=dp[i-1][j] dp[i][j]=dp[i1][j]
      • 选第 i i i种物品:选第 i i i种物品可能导致产生最优解,则选。集合状态仍为 [ 1 , i − 1 ] [1,i-1] [1,i1],因为0/1背包要求每种物品只能选一次,故继承自第 i − 1 i-1 i1种物品且背包容积减少 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[i1][jc[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[i1][j],dp[i1][jc[i]]+w[i])

遍历顺序:物品和背包谁先遍历都可以,根据状态转移方程式,dp数组的当前位置只与正上方和左上方有关,无论哪种遍历顺序,都可以确保在到达当前位置之前,正上方和左上方都有值。

初始化:

image-20240714203013557
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表

image-20240714135742848

滚动数组

DP问题的空间复杂度一般很高,可采用滚动数组方式对空间复杂度进行优化。

滚动数组原理是基于DP的无后效性,第 i i i行只与 i − 1 i-1 i1行有关,至于 i − 1 i-1 i1行之前的数据第 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[i1][j])或上一行左上方( d p [ i − 1 ] [ j − 1 ] dp[i-1][j-1] dp[i1][j1]),因此逆序遍历背包容量进行更新,可将数组压至一维。

必须对背包进行逆序更新,这样是为了满足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[i1][j],dp[i1][jc[i]]+w[i])可知,判断 d p [ i ] [ j ] dp[i][j] dp[i][j] d p [ i − 1 ] [ j ] dp[i-1][j] dp[i1][j] d p [ i − 1 ] [ j − c [ i ] ] + w [ i ] dp[i-1][j-c[i]]+w[i] dp[i1][jc[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最经典的类型之一&#xff0c;而0/1背包是最经典最基础的背包问题。 背包体积为 V V V&#xff0c; n n n种物品&#xff0c;每种物品只有1个&#xff0c;第 i i i种物品对应体积为 c i c_i ci​&#xff0c;价值为 w i w_i wi​&#xff0c;怎样装填能使…...

Linux的进程和权限的基本命令

目录 基本命令 man find date cal du ln exit grep 基本命令-帮助查询&#xff1a; wc cat more less head tail echo alias unalias 基本命令-进程管理&#xff1a; ps kill top 操作系统负载查看 用户分类&#xff1a; 程序用户 普通用户&#x…...

鼠标录制工具怎么挑选?9款电脑鼠标录制工具分享(2024)

你知道鼠标录制工具吗&#xff1f;鼠标录制工具通过记录和回放用户的操作&#xff0c;帮助自动化重复性任务&#xff0c;提高工作效率和精确性。它可以帮助用户简化很多繁琐的操作步骤&#xff0c;非常适合运用在电脑自动化任务、游戏自动化中&#xff0c;给大家整理了2024年9款…...

C1W4.LAB.Vector manipulation+Hash functions and multiplanes

理论课&#xff1a;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】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录 &#xff1a;《YOLOv8改进有效…...

数据采集监控平台:挖掘数据价值 高效高速生产!

在当今数字化的时代&#xff0c;数据已成为企业非常宝贵的资产之一。然而&#xff0c;要充分发挥数据的潜力&#xff0c;离不开一个强大的数据采集监控平台&#xff0c;尤其是生产制造行业。它不仅是数据的收集者&#xff0c;更是洞察生产的智慧之眼&#xff0c;高效高速处理产…...

【算法笔记自学】第 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 中&#xff0c;字符串常量和动态创建的字符串&#xff08;例如通过 stringWithFormat:、initWithString: 等方法创建的字符串&#xff09;在内存中保存的位置一样么 &#xff1f; 在 Objective-C 中&#xff0c;字符串常量和动态创建的字符串在内存中的保存位置…...

git 想要创建一个新的本地分支并检出远程分支的内容

如果你想要创建一个新的本地分支并检出远程分支的内容&#xff1a; git checkout -b feature-branch origin/feature-branch feature-branch 是你在本地创建的新分支名&#xff0c;origin/feature-branch 是远程分支的引用。 根据你检出的远程分支的名字而定 不知道名称的时…...

C语言学习笔记[24]:循环语句while②

getchar()的使用场景 int main() {char password[20] {0};printf("请输入密码&#xff1a;");//输入 123456 后回车scanf("%s", passwoed);//数组名本身就是数组地址printf("请确认密码&#xff1a;Y/N");int ch getchar();if(Y ch)printf(&…...

安全运营概述

安全运营概述 概述安全运营的工作对内安全运营工作对外安全运营工作品牌建设 概述 安全是一个过程&#xff0c;安全是靠运营出来的&#xff0c;公司会不断的有新业务的变更&#xff0c;新产品的发布&#xff0c;新版本的升级&#xff0c;技术架构的升级&#xff0c;底层系统的…...

spring-cloud和spring-cloud-alibaba的关系

首先Spring Cloud 是什么&#xff1f; Spring Cloud是一系列框架的有序集合&#xff0c;它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发。Spring Cloud提供了微服务架构开发所需的多种组件和工具&#xff0c;如服务发现注册、配置中心、消息总线、负载均…...

持续集成06--Jenkins构建触发器

前言 在持续集成&#xff08;CI&#xff09;的实践中&#xff0c;构建触发器是自动化流程中不可或缺的一环。它决定了何时启动构建过程&#xff0c;从而确保代码变更能够及时地得到验证和反馈。Jenkins&#xff0c;作为业界领先的CI/CD工具&#xff0c;提供了多种构建触发器选项…...

根据视图矩阵, 恢复相机的世界空间的位置

根据视图矩阵, 恢复相机的世界空间的位置 一、方法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&#xff08;单卡&#xff09;1.1 方法1&#xff1a;os.environ[CUDA_VISIBLE_DEVICES]1.2 方法2&#xff1a;torch.device(cuda:2)1.3 报错1&#xff1a;RuntimeError: CUDA error: invalid device ordinal CUDA kernel errors might be asy…...

python + Pytest + requests 的接口自动化步骤

pythonpytestrequestallureyaml接口自动化测试项目实战 开发环境准备 1. jdk 下载 Java官网下载地址&#xff1a;http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 安装&#xff1a; https://blog.csdn.net/VA_AV/article/details/138…...

基于若依的ruoyi-nbcio流程管理系统修正自定义业务表单的回写bug

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 http://218.75.87.38:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; h…...

GD32 MCU上电跌落导致启动异常如何解决

大家是否碰到过MCU上电过程中存在电源波动或者电压跌落导致MCU启动异常的问题&#xff1f;本视频将会为大家讲解可能的原因以及解决方法&#xff1a; GD32 MCU上下电复位波形如下图所示&#xff0c;上电过程中如果存在吃电的模块&#xff0c;比如wifi模块/4G模块/开启某块电路…...

安防视频监控/视频汇聚EasyCVR平台浏览器http可以播放,https不能播放,如何解决?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台基于云边端一体化架构&#xff0c;兼容性强、支持多协议接入&#xff0c;包括国标GB/T 28181协议、部标JT808、GA/T 1400协议、RTMP、RTSP/Onvif协议、海康Ehome、海康SDK、大华SDK、华为SDK、宇视SDK、乐橙SDK、萤石云SD…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...