Acwing-基础算法课笔记之动态规划(背包问题)

Acwing-基础算法课笔记之动态规划(背包问题)

  • 一、01背包问题
    • 1、概述
    • 2、过程模拟
  • 二、完全背包问题
    • 1、概述
    • 2、闫氏dp分析完全背包问题
    • 3、过程模拟
    • 代码模板
  • 三、多重背包问题
    • 1、概述
    • 2、过程模拟
    • 3、多重背包问题的优化版本
  • 分组背包问题
    • 1、概述
    • 2、过程模拟
    • 3、代码演示

一、01背包问题

1、概述

  1. 01背包中的0和1指的是放与不放,而且不能出现放多个的情况,背包只能放相同物品中的一个;
  2. 首先是对 d [ i ] [ j ] d[i][j] d[i][j] 数组的解释,该数组表示的是只看前 i i i 个物品,总体积是 j j j 的情况下,总价值最大是多少;

2、过程模拟

  1. 不选第 i i i个物品,只考虑前 i − 1 i-1 i1个物品, d p [ i ] [ j ] = d p [ i − 1 ] [ j ] dp[i][j]=dp[i-1][j] dp[i][j]=dp[i1][j]
  2. 选第 i i i个物品, d p [ i ] [ j ] = d p [ i − 1 ] [ j − v [ i ] ] dp[i][j]=dp[i-1][j-v[i]] dp[i][j]=dp[i1][jv[i]]
  3. d p [ i ] [ j ] = m a x { 1 , 2 } dp[i][j]=max\{1,2\} dp[i][j]=max{1,2}
  4. 初始条件,一个物品都不考虑 d p [ 0 ] [ 0 ] = 0 dp[0][0]=0 dp[0][0]=0

背包的最大容量为 6 6 6

物品体积 v v v价值 w w w
A A A 2 2 2 3 3 3
B B B 3 3 3 5 5 5
C C C 4 4 4 6 6 6
0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6
0 0 00000000
1 1 1 A ( 2 , 3 ) A(2,3) A(2,3)0
2 2 2 B ( 3 , 5 ) B(3,5) B(3,5)0
3 3 3 C ( 4 , 6 ) C(4,6) C(4,6)0

⇓ \Downarrow
∙ \bullet 对于每一个单元格 i . w e i g h t > j i.weight>j i.weight>j是否成立,按行填写

0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6
0 0 00000000
1 1 1 A ( 2 , 3 ) A(2,3) A(2,3)0033333
2 2 2 B ( 3 , 5 ) B(3,5) B(3,5)0
3 3 3 C ( 4 , 6 ) C(4,6) C(4,6)0

⇓ \Downarrow

0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6
0 0 00000000
1 1 1 A ( 2 , 3 ) A(2,3) A(2,3)0033333
2 2 2 B ( 3 , 5 ) B(3,5) B(3,5)0035588
3 3 3 C ( 4 , 6 ) C(4,6) C(4,6)0

⇓ \Downarrow

0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6
0 0 00000000
1 1 1 A ( 2 , 3 ) A(2,3) A(2,3)0033333
2 2 2 B ( 3 , 5 ) B(3,5) B(3,5)0035588
3 3 3 C ( 4 , 6 ) C(4,6) C(4,6)0035689

滚动dp一维数组版

0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6
0 0 00000000

⇓ \Downarrow

0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6
1 1 1 A ( 2 , 3 ) A(2,3) A(2,3)0033333

⇓ \Downarrow

0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6
2 2 2 B ( 3 , 5 ) B(3,5) B(3,5)0035588

⇓ \Downarrow

0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6
3 3 3 C ( 4 , 6 ) C(4,6) C(4,6)0035689

二、完全背包问题

1、概述

n n n件物品,每件物品的重量为 w [ i ] w[i] w[i],价值为 c [ i ] c[i] c[i]。现有一个容量为 V V V,的背包,问如何选取物品放入背包,使得背包物品的总价值最大。其中每件物品有无穷件。
既然这样,不妨像0-1背包问题那样,先写出状态转移方程,从源头上摸索。

2、闫氏dp分析完全背包问题

d p { 状态表示 ( i , j ) { 集合:所有只从前 i 个物品中选,总体积不超过 j 的方案的集合 属性: m a x 状态计算 d p [ i ] [ j ] = m a x ( d p [ i − 1 ] [ j ] , f [ i − 1 ] [ j − v ] + w 、 f [ i − 1 ] [ j − 2 v ] + 2 w 、 . . . . . . ) , d p [ i ] [ j − v ] = m a x ( d p [ i − 1 ] [ j − v ] , f [ i − 1 ] [ j − 2 v ] + w 、 f [ i − 1 ] [ j − 3 v ] + 2 w 、 . . . . . . ) + w ,两式组合 d p [ i ] [ j ] = m a x ( d p [ i − 1 ] [ j ] , f [ i ] [ j − v ] + w ) 如下图选第 i 个物品 dp\begin{cases} 状态表示(i,j)\begin{cases} 集合:所有只从前i个物品中选,总体积不超过j的方案的集合 \\ 属性:max \end{cases} \\ 状态计算dp[i][j]=max(dp[i-1][j],f[i-1][j-v]+w、f[i-1][j-2v]+2w、......),dp[i][j-v]=max(dp[i-1][j-v],f[i-1][j-2v]+w、f[i-1][j-3v]+2w、......)+w,两式组合dp[i][j]=max(dp[i-1][j],f[i][j-v]+w)如下图选第i个物品 \end{cases} dp 状态表示(i,j){集合:所有只从前i个物品中选,总体积不超过j的方案的集合属性:max状态计算dp[i][j]=max(dp[i1][j],f[i1][jv]+wf[i1][j2v]+2w......)dp[i][jv]=max(dp[i1][jv],f[i1][j2v]+wf[i1][j3v]+2w......)+w,两式组合dp[i][j]=max(dp[i1][j],f[i][jv]+w)如下图选第i个物品

在这里插入图片描述

3、过程模拟

例如:

容量j
组号物品体积v价值w01234567
0(无)0000000000
1小古银手办2100112233
2平板电脑3300133466
3笔记本电脑4500135568
4无价之宝5000135568

规律:
∙ \bullet j < v i j<v_i j<vi的时候, w i , j = w i − 1 , j w_{i,j}=w_{i-1,j} wi,j=wi1,j(解释:如果当前物品装不进背包,最大价值和前 i − 1 i-1 i1个物品的最大价值一样)
∙ \bullet j ≥ v i j\ge v_i jvi的时候, w i , j = m a x ( w i − 1 , j w_{i,j}=max(w_{i-1,j} wi,j=max(wi1,j不装,装 ) ) )(解释:如果装的下,在装和不装中选最大价值)

代码模板

int m = 0;
int n = 0;
cin >> m >> n;
int v[40] = {};
int w[40] = {};
for (int i = 1; i <= n; i ++){cin >> v[i] >> w[i];
}
int dp[40][210] = {};
for (int i = 1; i <= n; ++ i) {for (int j = 1; j <= m; ++ j) {if (j < v[i]) {dp[i][j] = dp[i - 1][j];}else {dp[i][j] = max(dp[i - 1][j], dp[i][j - v[i]] + w[i])}}
}
cout << "max = " << dp[n][m] <<endl;

优化版代码:

int m = 0;
int n = 0;
cin >> m >> n;
int v[40] = {};
int w[40] = {};
for (int i = 1; i <= n; i ++){cin >> v[i] >> w[i];
}
int dp[40][210] = {};
for (int i = 1; i <= n; ++ i) {for (int j = v[i]; j <= m; ++ j) {dp[j] = max(dp[j], dp[j - v[i]] + w[i])}
}
cout << "max = " << dp[n][m] <<endl;

三、多重背包问题

1、概述

求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大,但要注意的是,每件要取物品不能超过他给出的最大数量。

2、过程模拟

for(int i = 0; i < n; i ++)for(int j = m; j >= v[i]; j --)dp[j] = max(dp[j], dp[j - v[i]] + w[i], dp[j - 2 * v[i]] + 2 * w[i],......)//每件物品可以不去,可以取1个,或者取2个等等。

3、多重背包问题的优化版本

假设有一种物品有 s s s 件,若要将其拆分开来,则从 1 1 1 开始循环,每进行一次循环就乘 2 2 2,并每循环一次就减去迭代的变量 i i i,代码如下:

while (n--) {int v, w, s;scanf("%d%d%d", &v, &w, &s);for (int i = 1; i <= s; i *= 2) {s -= i;goods.push_back({ v * i,w * i });}if (s > 0)goods.push_back({ v * s,w * s });
}

分组背包问题

1、概述

N N N组物品和一个容量是 V V V的背包。每组物品有若干个,同一组内的物品最多只能选一个。每件物品的体积是 v i j v_{ij} vij,价值是 w i j w_{ij} wij,其中 i i i是组号, j j j是组内编号。

2、过程模拟

例如:
∙ \bullet 一个组只能选一个物品

组号物品体积v价值w
1小古银手办21
平板电脑33
2笔记本电脑45
3无价之宝50

以下是动态模拟:
∙ \bullet 每个组都有装和不装两种情况
∙ \bullet 如果装某个组的话,这个组只能装一次

容量j
组号01234567
000000000
10
20
30

3、代码演示

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 110;
int n, m;
int v[N], w[N], dp[N];
int main() {scanf("%d%d", &n, &m);while (n--) {int s;scanf("%d", &s);for (int i = 0; i < s; i++)scanf("%d%d", &v[i], &w[i]);for (int j = m; j >= 0; j--) {for (int k = 0; k < s; k++) {if (j >= v[k]) {dp[j] = max(dp[j], dp[j - v[k]] + w[k]);}}}}printf("%d", dp[m]);return 0;
}

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

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

相关文章

修改vscode的相对路径计算逻辑

vscode的相对路径计算逻辑是&#xff0c;"./"表示当前项目的文件夹&#xff0c;而不是当前文件所在的文件夹 做出如下修改&#xff1a; File-->Preferences-->settings 搜索Execute in File Dir , 然后取消勾选

粒子群算法对pi控制器进行参数优化,随时优化pi参数以控制直流无刷电机转速。

粒子群算法对pi控制器进行参数优化&#xff0c;随时优化pi参数以取得设定直流无刷电机转速。 PSO优化PID&#xff0c;用于BLDC速度控制 仿真平台为&#xff1a;MATLAB 采用的是Simulinkm程序相配合 仿真结果以及程序示例&#xff1a;

如何配置Apache的反向代理

目录 前言 一、反向代理的工作原理 二、Apache反向代理的配置 1. 安装Apache和相关模块 2. 配置反向代理规则 3. 重启Apache服务器 三、常见的使用案例 1. 负载均衡 2. 缓存 3. SSL加密 总结 前言 随着Web应用程序的不断发展和扩展&#xff0c;需要处理大量的请求和…

Excel第26享:模糊查找之Hlookup函数与通配符的嵌套

1、需求描述 如下图所示&#xff0c;现第一行有三个参考值&#xff1a;人S、羊E、猪3&#xff0c;在第三行有5个字&#xff1a;马、牛、人、羊、猪&#xff0c;每个字如果出现在第一行的三个参考值中&#xff0c;就返回该单元格的数值。如&#xff0c;人&#xff0c;就返回“人…

【SpringCloud微服务实战08】RabbitMQ 消息队列

MQ异步通信优缺点: 优点: 吞吐量提升:无需等待订阅者处理完成,响应更快速 故障隔离:服务没有直接调用,不存在级联失败问题 调用间没有阻塞,不会造成无效的资源占用 耦合度极低,每个服务都可以灵活插拔,可替换 流量削峰:不管发布事件的流量波动多大,都由Broker接收,…

Redis-复制功能

0 序言 复制功能是Redis提供的多机功能中最基础的一个&#xff0c;这个功能是通过主从复制&#xff08;master-slave replication&#xff09;模式实现的&#xff0c;它允许用户为存储着目标数据库的服务器创建出多个拥有相同数据库副本的服务器&#xff0c;其中存储目标数据库…

数据流的中位数

优质博文IT-BLOG-CN 一、题目 中位数是有序整数列表中的中间值。如果列表的大小是偶数&#xff0c;则没有中间值&#xff0c;中位数是两个中间值的平均值。 【1】 例如arr [2,3,4]的中位数是3。 【2】例如arr [2,3]的中位数是(2 3) / 2 2.5。 实现MedianFinder类: 【1】M…

​LLM之新手入门:大预言模型的概念介绍与应用

最近&#xff0c;我在系统地学习大型语言模型&#xff08;LLM&#xff09;的相关知识。在这个学习过程中&#xff0c;我努力将所学的内容整理成博客文章。在这篇博客中&#xff0c;我首先简要介绍了人工智能的发展历史&#xff0c;然后探讨了大型模型的基本原理、训练方法、微调…

Linux系列

安装系列 1.MySQL安装 我们要通过rpm&#xff0c;进行MySQL数据库的安装&#xff0c;主要的步骤如下&#xff1a; rpm -qa 查询当前系统中安装的所有软件 rpm -qa | grep mysql 查询当前系统中安装的名称带mysql的软件 rpm -…

uniapp微信小程序_拍照从相册选择

userImg() {let that thisuni.chooseMedia({count: 1,mediaType: [image, video],sourceType: [album, camera],maxDuration: 30,camera: back,success(res) {console.log(res.tempFiles[0].tempFilePath)that.imagUrl res.tempFiles[0].tempFilePath}})}, 直接调用api即可,注…

sqllab第十二关通关笔记

知识点&#xff1a; 一般字符型注入分类 单引号闭合双引号闭合这是一个双引号闭合 看界面又是一个输入框的注入;通过admin admin进行登录发现页面还是有回显 直接使用万能密码尝试 构造payload:usernameadminor11 没有任何反应&#xff1b;可能是没加注释符的关闭 构造user…

基于JAVA的教务系统小程序的设计与实现【附项目源码】分享

基于JAVA的教务系统小程序的设计与实现: 源码地址&#xff1a;https://download.csdn.net/download/qq_41810183/88842782 一、引言 随着信息技术的不断发展&#xff0c;教务管理工作逐渐走向数字化、智能化。为了提高教务管理效率&#xff0c;方便师生查询教务信息&#xff…

OpenAI的GPT-4.5 Turbo:意外曝光且可能在六月份推出

网络媒体THE DECODER的联合创始人兼出版人Matthias认为&#xff0c;人工智能技术将彻底改变人类和计算机的互动方式。 最新消息显示&#xff0c;OpenAI的最新力作GPT-4.5 Turbo已经在网络上意外曝光。首批发现此信息的是Bing和DuckDuck Go等搜索引擎&#xff0c;它们在官方发布…

8-图像放大

其实&#xff0c;就是开辟一个zoomwidth&#xff0c;zoomheight的内存&#xff0c;再分别赋值即可。 void CDib::Maginify(float xZoom, float yZoom) { //指向原图像指针 LPBYTE p_data GetData(); //指向原像素的指针 LPBYTE lpSrc; //指向缩放图像对应像素的指针 LPBYTE l…

【STM32中断EXTI详细介绍与总结】

STM32中断EXTI 中断的介绍中断简介中断优先级中断嵌套 STM32中断NVIC介绍作用功能如何分组 EXTI简介EXTI结构EXTI框图 AFIO介绍主要功能和作用&#xff1a; 中断配置步骤 一个中断时的代码初始化两个中断时的代码和错误提示 中断的介绍 中断简介 中断&#xff1a;在主程序运行…

亚信安慧AntDB在数据可靠性和系统安全中的实践

亚信安慧AntDB以持续创新和技术进步为理念&#xff0c;不断优化性能和功能&#xff0c;至今已经保持了15年的平稳运行。这一漫长的历程并非偶然&#xff0c;而是源于AntDB团队对技术的不懈探索和追求。他们始终秉承着“永不停歇&#xff0c;永不满足”的信念&#xff0c;将技术…

Jmeter扩展开发--自定义java取样器

简介 jmeter内置了包括&#xff1a;http、https、tcp等各种协议的支持&#xff0c;通常情况只需要做简单的参数配置即可使用。但在某些特殊情况下&#xff0c;还是希望能做自定义压测处理&#xff0c;此时就涉及Jmeter的扩展开发自定义Java取样器&#xff0c;如下图所示&#…

基于centos7的k8s最新版v1.29.2安装教程

k8s概述 Kubernetes 是一个可移植、可扩展的开源平台&#xff0c;用于管理容器化的工作负载和服务&#xff0c;可促进声明式配置和自动化。 Kubernetes 拥有一个庞大且快速增长的生态&#xff0c;其服务、支持和工具的使用范围相当广泛。 Kubernetes 这个名字源于希腊语&…

Github主页设置贪吃蛇详细教程

先看最终实现结果&#xff1a; 有条贪吃蛇放在主页还是蛮酷的哈哈哈。接下来我来讲一讲怎么在Github主页添加一条贪吃蛇。 首先要修改自己的Github的主页&#xff0c;我们得有一个特殊的仓库——这个仓库必须与你的Github用户名保持一致&#xff0c;并且需要公开&#xff0c…

力扣日记3.14-【贪心算法篇】376. 摆动序列

力扣日记&#xff1a;【贪心算法篇】376. 摆动序列 日期&#xff1a;2024.3.14 参考&#xff1a;代码随想录、力扣 376. 摆动序列 题目描述 难度&#xff1a;中等 如果连续数字之间的差严格地在正数和负数之间交替&#xff0c;则数字序列称为 摆动序列 。第一个差&#xff08;…