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

news2024/9/25 7:20:56

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.coloradmin.cn/o/1517653.html

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

相关文章

GCNv2_SLAM-CPU详细安装教程(ubuntu18.04)

GCNv2_SLAM-CPU详细安装教程-ubuntu18.04 前言一、安装第三方库1.安装Pangolin2.安装OpenCV3.安装Eigen4.安装Pytorch(c) 二、安装以及运行GCNv2_SLAM1.安装编译GCNv2_SLAM2.单目模式运行演示案例 总结 前言 paper:https://arxiv.org/pdf/1902.11046.pdf githup::https://gith…

mysql事务(MVCC机制:undo日志)(mysql执行过程:redo日志,Buffer Pool缓存池)

事务 目的&#xff1a;保证数据的最终一致性## 事务的目的 事务的4大特性&#xff08;ACID&#xff09; 1.原子性(Atomicity):由undo log日志来保证 2.一致性(Consistency):使用事务的最终目的&#xff0c;由业务代码正确逻辑保证,比如错误的try-catch 3.隔离性(Isolation):…

若依Vue3图片预览大图遮罩层和表格的border css层级冲突

样式层级出现问题&#xff0c;表格的层级高于图片的层级 1.解决方式一&#xff1a;设置此文件的该属性&#xff08;z-index&#xff09;为继承&#xff0c;则显示正常 .el-table .el-table__cell { z-index: inherit; } 2.解决方式二&#xff1a;将此属性设置为true(本人试了…

Vscode 修改C++版本

1. 首先要检查GCC版本&#xff0c;有的gcc版本过低会导致C版本升级不成功 可以用cmd&#xff0c;用gcc --version命令查看gcc版本 我这里就是gcc版本较低&#xff0c;不支持c17 需要先升级gcc版本 gcc与c对应的版本&#xff0c;大家可以在这位大佬的博客中看&#xff0c;写…

闯关升级游戏特点,闯关小程序游戏开发

闯关升级类游戏一直以来都备受玩家青睐&#xff0c;其独特的游戏性和吸引力让人们乐此不疲。这类游戏以挑战性关卡和角色成长为核心&#xff0c;让玩家在不断的冒险中获得成就感与乐趣。让我们一起深入探讨这类游戏的特点&#xff0c;以及为何它们如此受欢迎。 挑战性关卡设计…

FPGA - 串口发送多字节数据

1&#xff0c;任务要求 关于uart串口接收与发送可以参考我的这篇博客&#xff1a;《FPGA-UART串口》。这篇博客实现了单字节发送与接收。 接下来&#xff0c;来使用串口发送多字节数据到电脑。 2&#xff0c;模块框图以及简单时序分析图 串口发送多字节数据的思路是把写入的…

Windows提示“无法删除文件:无法读源文件或磁盘”怎么办?

当用户在Mac电脑上创建一个文件&#xff0c;又将文件共享到Windows系统后&#xff0c;该文件可能无法被Windows正常识别和使用&#xff0c;并且在删除时出现“无法删除文件&#xff1a;无法读源文件或磁盘”的提示&#xff0c;这可能和Windows不支持Mac电脑创建的某些文件名有关…

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

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

基于物联网的智能家居监测与控制系统(全套资料)

项目源码资料下载地址&#xff1a; http://comingit.cn/?id29 易学蔚来全套毕设演示&#xff08;看上哪个选那个&#xff09;&#xff1a; https://www.yuque.com/javagongchengshi/ccadbu/nh92kcpyqodhf07l 毕设服务真实反馈&#xff0c;在线观看&#xff1a; https://www.yu…

opencv中的图像高斯模糊—GaussianBlur

高斯模糊&#xff08;Gaussian Blur&#xff09;是一种广泛应用于图像处理的平滑技术&#xff0c;其通过对图像应用高斯函数来减少图像噪声和细节。与简单平均模糊&#xff08;均值滤波&#xff09;不同&#xff0c;高斯模糊给予中心像素更高的权重&#xff0c;而远离中心的像素…

介绍Oracle的SQL调化健康检查脚本(SQLHC)

概述 Oracle提供了一个SQL调优健康检查脚本&#xff08;SQLHC&#xff09;&#xff0c;用于检查需要优化的SQL的运行环境&#xff0c;生成报告以便帮助DBA找到SQL性能不佳的原因。SQLHC是SQLT的一个子集&#xff08;我后续的文章会介绍SQLT&#xff09;&#xff0c;但SQLHC与S…

#微信小程序(一个emo文案界面)

1.IDE&#xff1a;微信开发者工具 2.实验&#xff1a;一个emo文案界面 &#xff08;1&#xff09;最好使用rpx &#xff08;2&#xff09;图片宽度占不满&#xff0c;在CSS中设置width为100% &#xff08;3&#xff09;imag图片全部为网页链接图片 3.记录 4.代码 index.htm…

sqllab第二十关通关笔记

知识点&#xff1a; cookie注入 可以进行url解析错误注入传参位置 get请求post请求cookie传参 输入admin admin进行登录&#xff0c;抓取当前数据包 通过放包发现是一个302跳转的响应包&#xff0c;页面只有一个 I Love Cookies&#xff1b;没什么信息 通过点击页面上方的按钮…

Linux搭建FTP服务器

一、概念简介 vsftpd&#xff08;very secure FTP daemon&#xff09;是Linux下的一款小巧轻快、安全易用的FTP服务器软件&#xff0c;本次实验介绍如何在Linux上安装并配置vsftpd。 FTP&#xff08;File Transfer Protocol&#xff09;是一种文件传输协议&#xff0c;基于客户…

vue antd table嵌套表格 左侧展开图标动态控制显示隐藏

antd a-table想要实现如以下效果&#xff0c;有子级就显示展开图标&#xff0c;没有就不显示图标&#xff1a; 话不多说&#xff0c;直接上代码&#xff1a; <template><a-table :columns"columns" :data-source"dataSource"><template #b…

电机参数辨识算法(1)——基于高频注入的电感辨识策略

今天将开启参数辨识的第一期。通过复现论文来学习电机参数在线辨识的方法。我会尽可能讲述我在仿真遇到的问题以及解决办法。 1.文章内容介绍 参考文献如下&#xff1a; 这篇文章的复现估计要分为几个部分&#xff0c;电感辨识、电阻辨识、磁链辨识。 文章是以无差拍预测电流…

【MySQL】MySQL主从复制

目录 技术背景数据库架构演变1.单机MySQL数据库的美好年代2.Memcached(缓存)MySQL3.主从复制&#xff1a;读写分离4.垂直拆分业务数据5.分库分表 结论——生产环境的MySQL架构 什么是主从复制作用读写分离一主多从 应用场景原理解析MySQL主从复制工作方式master 记录二进制日志…

提升零售行业竞争力的信息抽取技术应用与实践

一、引言 在当今快速发展的零售行业中&#xff0c;沃尔玛、家乐福等大型连锁超市为消费者提供了丰富的日常食品和日用品。为了进一步提升客户体验和优化库存管理&#xff0c;这些零售巨头纷纷开始探索和应用先进的信息抽取技术。 本文将深入探讨一个成功的信息抽取项目&#…

vue iview 级联选择器遇到的坑

我们PC项目用到的前端技术栈是vue+iview,最近有个需求,要做个级联选择器,并且是懒加载动态加载后端返回的数据。效果如下: 如下图所示,在我们封装的公共组件form-box.vue里有我们级联选择器: 代码如下: <!--级联选择器--><template v-else-if="item.type…

【小白学机器学习9】自己纯手动计算验证,EXCEL的一元线性回归的各种参数值

目录 0 目标 1 构造模型 1.1 构造模型的思路 1.2 具体模型构造的EXCEL公式和过程 2 直接用EXCEL画图&#xff0c;然后生成趋势线的方式进行回归分析 2.1 先选择“观测值Y”的数据&#xff0c;用散点图或者折线图作图 2.2 然后添加趋势线和设置趋势线格式 2.3 生成趋…