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

蓝桥杯DP算法——背包问题(C++)

目录

一、01背包问题

二、完全背包问题

三、多重背包问题

四、多重背包问题(优化版)

五、分组背包问题


一、01背包问题

01背包问题就是有N件物品,一个空间大小为V的背包,每个物品只能使用一次,使得背包中所装物品的价值总和最大。

  如图所示使用一个二维数组来存放从前i个物品中取,总体积不超过j的包中价值最大值。

 根据图二所示,我们可以将每次dp到的情况分为两种,一种是选择第 i 件物品,另一种是不选择第 i 件物品。

  • (不含 i )就是从0~i-1中选择体积不超过 j 的物品,也就是f(i-1,j)
  • (含 i )即从 1 ~ i 中选,包含 i,且总体积不超过 j。可以先把第 i 个物品拿出来,即从第 1 ~ i-1中选,且总体积不超过 j-v[i],也就是f(i-1,j-v_{i})+w_{i}

最终:f[ i ][ j ] = max(f[ i-1 ][ j ], f[i-1][j-v[ i ]] +w[ i ]

例题:https://www.acwing.com/problem/content/2/

朴素做法: 

#include<iostream>
using namespace std;
const int N=1010;
int v[N],w[N];
int f[N][N];int main()
{int n,m;cin>>n>>m;for(int i =1;i<=n;i++) cin>>v[i]>>w[i];for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){f[i][j]=f[i-1][j];if(j>=v[i])//可以装的下{f[i][j]=max(f[i][j],f[i-1][j-v[i]]+w[i]);}}}cout<<f[n][m];return 0;
}

优化: 

 f[i] 只用到了 f[i-1] 这一层,即 f[i-2] 到 f[0] 对 f[i] 是没有用的,所以第二层循环可以直接从 v[i] 开始

for (int i = 1; i <= n; i++) {for (int j = v[i]; j <= m; j++) {f[i][j] = max(f[i][j], f[i - 1][j - v[i]] + w[i]);}
}

 从二维优化成一维(空间优化)

如果直接删除掉 f[i] 这一维即

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

但是这样直接删掉是错误,因为j是递增的。

原式:f[i][j] = max(f[i][j], f[i - 1][j - v[i]] + w[i]);

改成一维:f[j] = max(f[j], f[j - v[i]] + w[i]);

由于 f[i][] 只跟上一状态(f[i - 1][])有关 上面两个式子 :这一状态(左) = 上一状态(右)

即 f[i][j] 是由 f[i - 1][j - v[i]] 推出来的 现在进行空间优化,那么必须要保证 f[j] 要由 f[j - v[i]] 推出来的。

如果j层循环是递增的,则相当于 f[i][j] 变得是由 f[i][j - v[i]] 推出来的, 而不是 f[i - 1][j - v[i]] 推出来的。

优化后代码:

#include<iostream>
using namespace std;
const int N=1010;
int v[N],w[N];
int f[N];int main()
{int n,m;cin>>n>>m;for(int i =1;i<=n;i++) cin>>v[i]>>w[i];for(int i=1;i<=n;i++){for(int j=m;j>=v[i];j--){f[j]=max(f[j],f[j-v[i]]+w[i]);}}cout<<f[m];return 0;
}

二、完全背包问题

完全背包不同于01背包的是,每件物品都是无限使用的。

如图所示,与01背包相似的是每次选择0,1,2,3,4,5,....k个

不选时仍是 f[ i-1][ j ]

选择k件时是 f[ i-1][ j-k*v[i]] +k*w[i]

也就是:

                                                         f[ i-1][ j-k*v[i]] +k*w[i]

 例题:https://www.acwing.com/problem/content/3/

朴素写法: 

#include<iostream>
using namespace std;const int N=1010;
int n,m;
int v[N],w[N],f[N][N];int main()
{cin>>n>>m;for(int i=i;i<=n;i++) scanf("%d%d",&v[i],&w[i]);for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){for(int k=0;k*v[i]<=j;k++){f[i][j]=max(f[i][j],f[i-1][j-k*v[i]]+w[i]*k);}}}cout<<f[n][m];return 0;
}

优化:

在对完全背包问题优化时,我们由图公式可知f[i][j]可以简化为max(f[i-1][j],f[i][j-v]+w)

优化后代码:

#include <iostream>
#include <algorithm>using namespace std;const int N=1010;
int f[N];
int v[N],w[N];
int n,m;
int main()
{cin>>n>>m;for(int i=1;i<=n;i++) cin>>v[i]>>w[i];for(int i=1;i<=n;i++){for(int j=v[i];j<=m;j++){f[j]=max(f[j],f[j-v[i]]+w[i]);}}cout<<f[m];return 0;
}

三、多重背包问题

多重背包问题相较于之前的问题就是每个物品是有限s个。 

例题:https://www.acwing.com/problem/content/4/

#include<iostream>
using namespace std;
const int N=110;int n,m;
int s[N],v[N],w[N];
int f[N][N];int main()
{cin>>n>>m;for(int i=1;i<=n;i++) cin>>v[i]>>w[i]>>s[i];for(int i=1;i<=n;i++){for(int j=0;j<=m;j++){for(int k=0;k<=s[i]&&j>=(k*v[i]);k++){f[i][j]=max(f[i][j],f[i-1][j-v[i]*k]+w[i]*k);}}}cout<<f[n][m];return 0;
}

四、多重背包问题(优化版)

首先我们以之前完全背包问题的优化方法尝试使用另一个表达式来代替,但是结果如图所示,不是很好解决。 

二进制法优化:二进制优化的方法在于使用二进制的表示方式来代替每个物品的个数,当某件物品的个数很多的时候无需从1遍历循环到n,可以将其分解成log_{_{2}^{}}^{n}个位权来表示。

为了方便理解举个例子:

如果要拿1001次苹果,传统就是要拿1001次;二进制的思维,就是拿7个箱子就行(分别是装有512、256、128、64、32、8、1个苹果的这7个箱子),这样一来,1001次操作就变成7次操作就行了。

但是要注意的一点是如果某件物品的个数不是二次幂减一,就将前一位的值与s差值记为下一个位权。这样就可以表示0~s之内的所有数了。

然后就将问题分解成为了,01背包问题。

例题:https://www.acwing.com/problem/content/5/

#include<iostream>
using namespace std;const int N=11010,M=2010;
int v[N],w[N];
int f[N];int main()
{int n,m;cin>>n>>m;int cnt=0;while(n--)//初始化v[] w[]{int a,b,s;cin>>a>>b>>s;int k=1;while(k<=s){cnt++;v[cnt]=a*k;w[cnt]=b*k;s-=k;k*=2;}if(s>0){cnt++;v[cnt]=a*s;w[cnt]=b*s;}}n=cnt;//01背包for(int i=1;i<=n;i++){for(int j=m;j>=v[i];j--){f[j]=max(f[j],f[j-v[i]]+w[i]);}}cout<<f[m];return 0;
}

五、分组背包问题

分组背包问题的不同于之前背包问题的地方在于分组背包是将物品分成几组,然后再在每组里面选择一个物品,并且每组只能选择一个物品。

这里的dp状态计算与之前的也有所不同,这里表示的是第i组选哪一个,f[i-1][j]是表示不选择这一组的物品,f[i-1][j-v[i,k]]+w[i,k]表示的是这一组中选择哪一个。 

例题: https://www.acwing.com/problem/content/9/

#include<iostream>
using namespace std;const int N=110;
int n,m;
int s[N],v[N][N],w[N][N];
int f[N];int main()
{cin>>n>>m;for(int i=1;i<=n;i++){cin>>s[i];for(int j=1;j<=s[i];j++){cin>>v[i][j]>>w[i][j];}}for(int i=1;i<=n;i++){for(int j=m;j>=0;j-- ){for(int k=0;k<=s[i];k++){if(v[i][k]<=j){f[j]=max(f[j],f[j-v[i][k]]+w[i][k]);}}}}cout<<f[m];return 0;
}

相关文章:

蓝桥杯DP算法——背包问题(C++)

目录 一、01背包问题 二、完全背包问题 三、多重背包问题 四、多重背包问题&#xff08;优化版&#xff09; 五、分组背包问题 一、01背包问题 01背包问题就是有N件物品&#xff0c;一个空间大小为V的背包&#xff0c;每个物品只能使用一次&#xff0c;使得背包中所装物品…...

【LeetCode+JavaGuide打卡】Day22|235. 二叉搜索树的最近公共祖先、701.二叉搜索树中的插入操作、450.删除二叉搜索树中的节点

学习目标&#xff1a; 235. 二叉搜索树的最近公共祖先 701.二叉搜索树中的插入操作 450.删除二叉搜索树中的节点 学习内容&#xff1a; 235. 二叉搜索树的最近公共祖先 题目链接&&文章讲解 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最…...

Stable Diffusion WebUI 界面介绍

本文收录于《AI绘画从入门到精通》专栏,专栏总目录:点这里。 大家好,我是水滴~~ 本文主要对 Stable Diffusion WebUI 的界面进行简单的介绍,让你对该 WebUI 有个大致的了解,为后面的深入学习打下一个基础。主要内容包括:Stable Diffusion 模型(Stable Diffusion checkp…...

Cocos2dx-lua ScrollView[一]基础篇

一.ScrollView概述 cocos游戏中ScrollView控件大量使用,95%以上的项目都会使用ScrollView,个别游戏可能全部使用翻页的滑动效果。如果想要精通Cocos的UI开发,精通ScrollView控件非常关键,因此对ScrollView的使用进行总结很有必要。 下文缩写说明:sv = ScrollView, item代…...

QT应用软件【协议篇】周立功CAN接口卡代码示例

文章目录 USBCAN系列CAN接口卡规格参数资料下载QT引用周立功的库安装sdk代码USBCAN系列CAN接口卡 USBCAN系列CAN接口卡兼容USB2.0全速规范,可支持1/2/4/8路CAN接口。采用该接口卡,PC机可通过USB连入CAN网络,进行CAN总线数据采集和处理,主要具备以下几大优势特点: 支持车载…...

JVM对象的创建流程与内存分配

对象的创建流程与内存分配 创建流程对象内存分配方式内存分配安全问题对象内存分配流程【重要】:对象怎样才会进入老年代?重点 案例演示:对象分配过程大对象直接进入老年代02-对象内存分配的过程: 创建流程 加载 验证 解析 准备 初始化 使用 写在 对象内存分配方式 内存分配…...

docker (六)-进阶篇-数据持久化最佳实践MySQL部署

容器的数据挂载通常指的是将宿主机&#xff08;虚拟机或物理机&#xff09;上的目录或文件挂载到容器内部 MySQL单节点安装 详情参考docker官网文档 1 创建对应的数据目录、日志目录、配置文件目录(参考二进制安装&#xff0c;需自己建立数据存储目录) mkdir -p /data/mysq…...

力扣题目训练(17)

2024年2月10日力扣题目训练 2024年2月10日力扣题目训练551. 学生出勤记录 I557. 反转字符串中的单词 III559. N 叉树的最大深度241. 为运算表达式设计优先级260. 只出现一次的数字 III126. 单词接龙 II 2024年2月10日力扣题目训练 2024年2月10日第十七天编程训练&#xff0c;今…...

【react】react中和vue中的provide/inject、context写法示例

react写法 在 React 中&#xff0c;provide和inject的功能类似于 Vue.js 中的 provide和inject。它们都是用于跨组件层次传递数据的。 在 React 中&#xff0c;没有内置的 provide 和 inject 函数。但是&#xff0c;你可以使用 React 的 Context 来实现类似的功能。 Context…...

MySQL 的存储引擎(基本介绍)

文章目录 前言MySQL 的存储引擎介绍存储引擎是什么&#xff1f;存储引擎的特性? Innodb 与 Mylsam 的区别行级锁与表级锁是否支持事务是否支持恢复数据是否支持外键是否支持 MVCC 总结 前言 好文章不要错过&#xff0c;前两天跟大家分享的文章 1.MySQL的基础架构 2.SQL语句的…...

Unity3D 实现基于物理引擎的绳子关节解析详解

前言 在游戏开发中&#xff0c;有时候我们需要实现绳子关节效果&#xff0c;比如在射击游戏中射击绳子&#xff0c;或者在平衡游戏中使用绳子作为支撑。本文将详细介绍如何使用Unity3D的物理引擎实现绳子关节效果。 对惹&#xff0c;这里有一个游戏开发交流小组&#xff0c;希…...

C语言二级易忘易错易混知识点(自用)

1.数组名不能自加。 因为数组名实际上是一个指针&#xff0c;指向数组的第一个元素的地址。数组名在编译器中被视为常量&#xff0c;它的值是固定的&#xff0c;不能改变。 要访问数组的不同元素&#xff0c;应该使用数组名加上偏移量的方式来访问。 2.共用体只有最后一次赋值…...

js_三种方法实现深拷贝

深拷贝&#xff08; 递归 &#xff09; 适用于需要完全独立于原始对象的场景&#xff0c;特别是当对象内部有引用类型时&#xff0c;为了避免修改拷贝后的对象影响到原始对象&#xff0c;就需要使用深拷贝。 // 原始对象 const obj { uname: Lily,age: 19,hobby: [乒乓球, 篮球…...

【图论经典题目讲解】CF715B - Complete The Graph

C F 715 B − C o m p l e t e T h e G r a p h \mathrm{CF715B - Complete\ The\ Graph} CF715B−Complete The Graph D e s c r i p t i o n \mathrm{Description} Description 给定一张 n n n 个点&#xff0c; m m m 条边的无向图&#xff0c;点的编号为 0 ∼ n − 1 0\…...

[office] excel中数据汇总的大全教程文字版 #知识分享#经验分享#知识分享

excel中数据汇总的大全教程文字版 我们在excel中对数据清单上的数据进行分析的一种方法是分类汇总。在“数据”菜单上选择“分类汇总”命令&#xff0c;我们可以在数据清单中插入分类汇总行&#xff0c;然后按照选择的方式对数据进行汇总。同时&#xff0c;在插入分类汇总时&am…...

leetcode经典题库(简单)

文章目录 1.两数之和2.反转链表3.合并两个有序列表4.合并两个有序链表5.删除有序数组中的重复项6.从数组中移除元素7. 搜索指定数值在数组中的插入位置8. 数组最后一位加一9. 合并两个有序数组在leetcode上刷了几个和数组相关的简单题,记录在这里。 1.两数之和 给定一个整数…...

python coding with ChatGPT 打卡第21天| 二叉树:最近公共祖先

相关推荐 python coding with ChatGPT 打卡第12天| 二叉树&#xff1a;理论基础 python coding with ChatGPT 打卡第13天| 二叉树的深度优先遍历 python coding with ChatGPT 打卡第14天| 二叉树的广度优先遍历 python coding with ChatGPT 打卡第15天| 二叉树&#xff1a;翻转…...

openGauss学习笔记-224 openGauss性能调优-系统调优-数据库系统参数调优-数据库并发队列参数调优

文章目录 openGauss学习笔记-224 openGauss性能调优-系统调优-数据库系统参数调优-数据库并发队列参数调优224.1 全局并发队列224.2 局部并发队列 openGauss学习笔记-224 openGauss性能调优-系统调优-数据库系统参数调优-数据库并发队列参数调优 数据库提供两种手段进行并发队…...

UE5 C++ 创建可缩放的相机

一.要将相机设置在Pawn类里 1.在MyPawn头文件里&#xff0c;加上摇臂和相机组件 #include "GameFramework/SpringArmComponent.h" #include "Camera/CameraComponent.h" 2.在Pawm里声明SceneComponet&#xff0c;SpringArmComponent,CameraComponent组件…...

Fabric中的溯源方法

背景 在Fabric链码中&#xff0c;我们可以使用PutState方法对一个key的值进行覆盖&#xff0c;当我们再使用GetState查询时是最新的值。如果我们希望找到这个key的修改记录&#xff0c;我们可以使用溯源方法GetHistoryForKey。完整源码链接&#xff1a;https://github.com/hyp…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...

GitHub 趋势日报 (2025年06月06日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

windows系统MySQL安装文档

概览&#xff1a;本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容&#xff0c;为学习者提供全面的操作指导。关键要点包括&#xff1a; 解压 &#xff1a;下载完成后解压压缩包&#xff0c;得到MySQL 8.…...

LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用

中达瑞和自2005年成立以来&#xff0c;一直在光谱成像领域深度钻研和发展&#xff0c;始终致力于研发高性能、高可靠性的光谱成像相机&#xff0c;为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...

从物理机到云原生:全面解析计算虚拟化技术的演进与应用

前言&#xff1a;我的虚拟化技术探索之旅 我最早接触"虚拟机"的概念是从Java开始的——JVM&#xff08;Java Virtual Machine&#xff09;让"一次编写&#xff0c;到处运行"成为可能。这个软件层面的虚拟化让我着迷&#xff0c;但直到后来接触VMware和Doc…...

Python实现简单音频数据压缩与解压算法

Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中&#xff0c;压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言&#xff0c;提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...