【DP】背包问题全解

一.简介

DP(动态规划)背包问题是一个经典的组合优化问题,通常用来解决资源分配的问题,如货物装载、投资组合优化等。问题的核心思想是在有限的资源约束下,选择一组物品以最大化某种价值指标,通常是总价值或总利润。


二.闫氏DP分析法


三.01背包

(1)概念

每个物品只有一个,要么选,要么不选

(2)状态转移方程

f[i][j] = max(f[i-1][j] , f[i-1][j-v]+w)

(3)经典例题

P1048 [NOIP2005 普及组] 采药 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

(4)代码

#include<bits/stdc++.h>
#define N 1010
using namespace std;
int f[N][N];
int w[N],c[N];
int bag,n;
int main(){scanf("%d%d",&bag,&n);for(int i=1;i<=n;i++) scanf("%d%d",&w[i],&c[i]);for(int i=1;i<=n;i++){for(int j=0;j<=bag;j++){f[i][j]=f[i-1][j];if(j>=w[i]){f[i][j]=max(f[i][j],f[i-1][j-w[i]]+c[i]);}}}printf("%d",f[n][bag]);return 0;
}

(5)滚动数组优化 

#include<bits/stdc++.h>
#define N 1010
using namespace std;
int f[N];
int n,m;
int main()
{scanf("%d%d", &m, &n);for(int i = 1; i <= n; i ++ ){int w,c;scanf("%d%d", &w, &c);for(int j = m; j >=w ; j -- ){ f[j] = max(f[j], f[j-w] + c);}}printf("%d", f[m]);return 0;
}


四.完全背包

(1)概念

每个物品有无限个

(2)例题

1023. 买书 - AcWing题库

(3)闫氏DP分析法

(4)状态转移方程推导

f[i][j] = f[i - 1][j] + f[i - 1][j - v * 1]  + f[i - 1][j - v * 2] + ...... +  f[i -1][j - v * k];

f[i][j - v] =            f[i - 1][j - v * 1]  + f[i - 1][j - v * 2] + ...... +  f[i - 1][j - v * k];

所以推出:f[i][j] = f[i - 1][j] + f[i][j - v];

再使用滚动数组简化,就得出结论,其实就是01背包,内循环从大到小变成了从小到大!

(5)参考代码

#include<bits/stdc++.h>
#define N 1010
using namespace std;
int f[N];
int n;
int a[5] = {0, 10, 20, 50, 100};int main(){scanf("%d", &n);f[0] = 1; for(int i = 1; i <= 4; i ++ ){for(int j = a[i]; j <= n; j ++ ){f[j] += f[j - a[i]];}}	printf("%d", f[n]);return 0;
}


五.多重背包

(1)概念

物品有一定的数量

(2)实现方式

1.朴素版(易)  2.二进制优化版(中)  3.单调队列优化版(难)

(3)经典例题

1019. 庆功会 - AcWing题库

(3)朴素版

#include<bits/stdc++.h>
#define N 6010
using namespace std;
int f[N];
int n, m;
int main(){scanf("%d%d", &n, &m); //n个物品,m容量 for(int i = 1;i <= n; i ++ ){int v, w, s; //容量,价值,数量 scanf("%d%d%d", &v, &w, &s);for(int j = m; j >= v; j -- ){ //枚举容量 for(int k = 1;k <= s && k * v <= j; k ++ ){ //再枚举数量 f[j] = max(f[j], f[j - k * v] + w * k);}}}printf("%d", f[m]);return 0;
}

 (4)二进制优化版

#include<bits/stdc++.h>
#define N 6010
using namespace std;
int f[N];
int n,m;
int main(){scanf("%d%d", &n, &m);for(int i = 1; i <= n ; i ++ ){int v, w, s;scanf("%d%d%d", &v, &w, &s);for(int k = 1; k <= s; k *= 2) //二进制分解{for(int j = m; j >= k * v; j --)f[j] = max(f[j], f[j - k * v] + k * w);s -= k;}if(s) //余下的{for(int j = m; j >= s * v; j --)f[j] = max(f[j], f[j - s * v] + s * w);}}printf("%d", f[m]);return 0;
}

六.分组背包

(1)概念

每组物品有若干个,同一组内的物品最多只能选一个。

和多重背包十分相似,也简单。难得写了,copy一下,哈哈。


七.混合背包

(1)概念

就是把完全背包,多重背包,01背包混合起来,分类讨论即可,代码很好看懂。

(2)例题

7. 混合背包问题 - AcWing题库

(3)参考代码

#include<bits/stdc++.h>
#define N 1010
using namespace std;
int f[N];
int n,m;
int main()
{scanf("%d%d", &n, &m);int v, w, s;for(int i = 1; i <= n; i ++ ){scanf("%d%d%d", &v, &w, &s);if(s == 0){for(int j = v; j <= m; j ++ )f[j] = max(f[j], f[j - v]);}else{if(s == -1) s = 1;for(int k = 1; k <= s; k *= 2){for(int j = m; j >= k * v; j --)f[j] = max(f[j], f[j - k * v] + k * w);s -= k;}if(s){for(int j = m; j >= s * v; j --)f[j] = max(f[j], f[j - s * v] + s * w);}}}printf("%d", f[m]);return 0;
}

八.有依赖的背包

(1)例题

10. 有依赖的背包问题 - AcWing题库

(2)参考代码

#include<iostream>
#include<vector>
using namespace std;
int f[110][110];//f[x][v]表达选择以x为子树的物品,在容量不超过v时所获得的最大价值
vector<int> g[110];
int v[110],w[110];
int n,m,root;int dfs(int x)
{for(int i=v[x];i<=m;i++) f[x][i]=w[x];//点x必须选,所以初始化f[x][v[x] ~ m]= w[x]for(int i=0;i<g[x].size();i++){int y=g[x][i];dfs(y);for(int j=m;j>=v[x];j--)//j的范围为v[x]~m, 小于v[x]无法选择以x为子树的物品{for(int k=0;k<=j-v[x];k++)//分给子树y的空间不能大于j-v[x],不然都无法选根物品x{f[x][j]=max(f[x][j],f[x][j-k]+f[y][k]);}}}
}int main()
{cin>>n>>m;for(int i=1;i<=n;i++){int fa;cin>>v[i]>>w[i]>>fa;if(fa==-1)root=i;elseg[fa].push_back(i);}dfs(root);cout<<f[root][m];return 0;
}

九.二维费用背包

(1)简介

其实就是多了一维,和一维费用没啥区别

二维背包可以结合上述所有背包!

(2)例题

8. 二维费用的背包问题 - AcWing题库

(3)参考代码

#include<bits/stdc++.h>
#define maxn 1005
using namespace std;
int f[maxn][maxn];
int n,V,M;
int main(){scanf("%d%d%d",&n,&V,&M);for(int i=1;i<=n;i++){int v,m,w;scanf("%d%d%d",&v,&m,&w);//就是这里多了一维,多了一个循环,很好理解for(int j=V;j>=v;j--){for(int k=M;k>=m;k--){f[j][k]=max(f[j][k],f[j-v][k-m]+w);}}}printf("%d",f[V][M]);return 0;
}

十.总结

1.只有完全背包是正序遍历的,其他背包都是倒序遍历!

2.背包模型显而易见都是题目中给有一定的约束,如:有个多大容积的背包,有多少钱,等等。然后就是有几种方案,又给出相其对应的代价和贡献,最后求MAX or Count。

3.DP核心就在于熟练掌握闫氏DP分析法和题刷多了,积累了足够多的状态转移方程。

4.其实背包问题并不难,待到题刷够了,一切就迎刃而解了!加油!!!

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

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

相关文章

【Java 进阶篇】Java与JQuery选择器:解锁前端开发的魔法大门

在前端开发的世界中&#xff0c;选择器是我们与HTML文档进行互动的钥匙&#xff0c;而Java和JQuery则为我们提供了强大的工具&#xff0c;使得前端开发不再是一个艰深的谜题。本篇博客将围绕Java与JQuery选择器展开&#xff0c;深入解析选择器的奥秘&#xff0c;为你打开前端开…

Qt文档阅读笔记-Fetch More Example解析

Fetch More Example这个例子说明了如何在视图模型上添加记录。 这个例子由一个对话框组成&#xff0c;在Directory的输入框中&#xff0c;可输入路径信息。应用程序会载入路径信息的文件信息等。不需要按回车键就能搜索。 当有大量数据时&#xff0c;需要对视图模型进行批量增…

宝塔开心版hostcli的广告去除

首先感谢hostcli把宝塔7.6剥离了&#xff0c;直接安装我这里是缺少pyenv的包。 直接进入正题吧。 定位到页面左下方的广告位于 /www/server/panel/BTPanel/templates/default/layout.html “退出”按钮下方有条线开始去掉 去掉之前的忘了截图了&#xff0c;就这样吧&#xff…

《QT从基础到进阶·十七》QCursor鼠标的不同位置坐标获取

一些常用鼠标图形&#xff1a; 鼠标光标相对于整个电脑屏幕的位置&#xff1a;QCursor::pos() 当前光标相对于当前窗口的位置&#xff1a;this->mapFromGlobal(QCursor::pos()) void MainWindow::mouseReleaseEvent(QMouseEvent* event) {QPoint pos event->pos(); …

06-解决Spirng中的循环依赖问题

Bean的循环依赖问题 循环依赖: A对象中有B属性 , B对象中有A属性(丈夫类Husband中有Wife的引用, 妻子类Wife中有Husband的引用) toString()方法重写时直接输出wife/husband会出现递归导致的栈内存溢出错误 直接输出wife/husband会调用它们的toString()方法, 在toString()方法…

Spring的Redis客户端

如何在Spring中操作redis 在创建springboot项目的时候引入redis的依赖. 在配置文件里指定redis主机的地址和端口,此处我们配置了ssh隧道,所以连接的就是本机的8888端口. 创建一个controller类,注入操作redis的对象. 前面使用jedis,是通过jedis对象里的各种方法来操作redis的,此…

在任何机器人上实施 ROS 导航堆栈的指南

文章目录 路径规划参考 路径规划 路径规划是导航的最终目标。这允许用户向机器人给出目标姿势&#xff0c;并让它在给定的环境中自主地从当前位置导航到目标位置。这是我们迄今为止所做的一切&#xff08;地图绘制和本地化&#xff09;的汇集点。ROS 导航堆栈已经为我们完成了…

通讯协议学习之路(实践部分):SPI开发实践

通讯协议之路主要分为两部分&#xff0c;第一部分从理论上面讲解各类协议的通讯原理以及通讯格式&#xff0c;第二部分从具体运用上讲解各类通讯协议的具体应用方法。 后续文章会同时发表在个人博客(jason1016.club)、CSDN&#xff1b;视频会发布在bilibili(UID:399951374) 本文…

【PG】PostgreSQL 预写日志(WAL)、checkpoint、LSN

目录 预写式日志&#xff08;WAL&#xff09; WAL概念 WAL的作用 WAL日志存放路径 WAL日志文件数量 WAL日志文件存储形式 WAL日志文件命名 WAL内容 检查点&#xff08;checkpoint&#xff09; 1 检查点概念 2 检查点作用 触发检查点 触发检查点之后数据库操作 设置合…

四入进博会,优衣库围绕科技可持续演绎“服装进化论”

11月5日&#xff0c;第六届中国国际进口博览会在上海拉开帷幕。这些年来&#xff0c;进博巨大的平台效应&#xff0c;使其成为各个行业头部品牌的秀场&#xff0c;也持续为消费者、产业链带来惊喜。 今年&#xff0c;也是全球服装界科技知名品牌——优衣库的第四次进博之旅。从…

Python爬虫爬取家纺数据并分析

因为时间的原因&#xff0c;没法写一个详细的教程&#xff0c;但是我可以提供一个基本的框架。你需要根据实际情况进行修改和扩展。以下是使用Python的requests库和BeautifulSoup库来爬取网页内容的基本步骤&#xff1a; # 导入所需的库 import requests from bs4 import Beaut…

2023/11/13JAVA学习

字节数组增大的同时,运行速度也会加快,但是大到一定程度就不行了 要想追加数据,要在低级流后面加true,高级流后面加不了 不是乱码,不是让人看的 保持数据一一对应 否则会报错 下载后,拷贝到一个包里,再 comment是你想添加的注释 txt文本也可

[算法训练营] 贪心算法专题(二)

&#x1f57a;作者&#xff1a; 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux菜鸟刷题集 &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f3c7;码字不易&#xff0c;你的&#x1f44d;点赞&#x1f64c;收藏❤️关注对我真的…

Day02_《MySQL索引与性能优化》

文章目录 一、SQL执行顺序二、索引简介1、关于索引2、索引的类型Btree 索引Btree 索引 三、Explain简介四、Explain 详解1、id2、select_type3、table4、type5、possible_keys6、key7、key_len8、ref9、rows10、Extra11、小案例 五、索引优化1、单表索引优化2、两表索引优化3、…

RT-DETR算法优化改进:一种新颖的动态稀疏注意力(BiLevelRoutingAttention) | CVPR2023

💡💡💡本文独家改进: 提出了一种新颖的动态稀疏注意力(BiLevelRoutingAttention),以实现更灵活的计算分配和内容感知,使其具备动态的查询感知稀疏性 1)代替RepC3进行使用; 2)BiLevelRoutingAttention直接作为注意力进行使用; 推荐指数:五星 RT-DETR魔术师专栏介…

leetcode刷题日记:118.Pascal‘s Triangle(杨辉三角)

118.Pascal’s Triangle(杨辉三角&#xff09; 题目给我们一个整数numRows表示杨辉三角形的行数&#xff0c;返回杨辉三角形的前numRows行&#xff0c;下面给出一个杨辉三角形看看它有哪些规律&#xff1b; 可以看出杨辉三角形的每一行的最左侧和最右侧的值都为1. 其余的第…

Marin说PCB之 PCB封装和原理图封装的藕断丝连

最近天气开始降温了&#xff0c;小编我不得不拿出珍藏多年的秋裤穿上了&#xff0c;就是走路不太方便&#xff0c;有点紧啊&#xff0c;可能是当时衣服尺码买小了吧&#xff0c;不可能是我吃胖了&#xff0c;这个绝对不可能。 话说小编我今年属实有点走霉运啊&#xff0c;下班和…

虚拟仪器软件结构VISA

1、什么是VISA VISA是虚拟仪器软件结构(Virtual Instrument Software Architectuere)的简称&#xff0c;是由VXI plug & play系统联盟所统一制定的I/O接口软件标准及其相关规范的总称。一般称这个I/O函数库为VISA库&#xff08;用于仪器编程的标准I/O函数库&#xff09;。…

Allegro层叠中的Etch Factor-铜皮的腐蚀因子如何计算

Allegro层叠中的Etch Factor-铜皮的腐蚀因子如何计算 在用Allegro进行PCB设计的时候,Cross-section中需要填入对应的信息,一般填入每层的厚度即可,如下图 当PCB需要进行仿真分析的时候,Etch-Factor这个值是必须要填写的,如下图 目前看到的都是90这个值,这是一个理论值。 …

app软件开发多少钱?功能会影响价格吗?

随着智能手机的普及&#xff0c;app开发市场日益繁荣&#xff0c;很多人都有开发app的梦想&#xff0c;但开发一款app需要多少钱呢?功能是否会影响价格?本文将为你揭开这个谜团。 一、app开发费用的影响因素 app开发费用受到多种因素的影响&#xff0c;例如开发难度、功能复…