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

动态规划(Dynamic Programming)——背包问题

动态规划(Dynamic Programming)

背包问题

目录

    • 动态规划(Dynamic Programming)
      • 背包问题
        • 01背包问题
          • 输入格式
          • 输出格式
          • 数据范围
          • 输入样例
          • 输出样例:
          • 二维
          • 一维
        • 完全背包问题
        • 多重背包问题
          • 输入格式
          • 输出格式
          • 数据范围
          • 输入样例
          • 输出样例:
          • 数据范围
          • 二进制优化
        • 分组背包问题
          • 输入格式
          • 输出格式
          • 数据范围
          • 输入样例
          • 输出样例:

01背包问题

动态规划

  • 状态表示 f[i][j]
    • 集合:所有考虑前i个物品,且体积不大于j的全部选法
    • 属性:Max
  • 状态计算:集合的划分

有 N件物品和一个容量是 V的背包。每件物品只能使用一次。

第 i 件物品的体积是 viv_ivi,价值是wiw_iwi

求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出最大价值。

输入格式

第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积。

接下来有 N 行,每行两个整数 vi,wiv_i,w_ivi,wi,用空格隔开,分别表示第 i 件物品的体积和价值。

输出格式

输出一个整数,表示最大价值。

数据范围

0<N,V≤10000<N,V≤1000
0<vi,wi≤10000< vi,wiv_i,w_ivi,wi≤1000

输入样例
4 5
1 2
2 4
3 4
4 5
输出样例:
8
二维
  • 状态f[i][j]定义:前 i个物品,背包容量 j下的最优解(最大价值)

  • 当背包容量够,需要决策选与不选第 i 个物品:

    • 不选f[i][j] = f[i-1][j]
    • f[i][j]=f[i-1][j-v[i]]+w[i]
    • 我们的决策是如何取到最大价值,因此以上两种情况取max()

    代码

    #include <iostream>
    #include <algorithm>
    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 (v[i] <= j)  f[i][j] = max(f[i][j], f[i -1][j - v[i]] + w[i]);}}cout << f[n][m];return 0;
    }
    
一维

我们定义的状态f[i][j]可以求得任意合法的i与j最优解,但题目只需要求得最终状态f[n][m],因此我们只需要一维的空间来更新状态。

#include <iostream>
#include <algorithm>
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;
}

完全背包问题

动态规划

  • 状态表示 f[i][j]
    • 集合:所有考虑前i个物品,且体积不大于j的全部选法
    • 属性:Max
  • 状态计算:集合的划分

f[i][j]第i个物品选了k个,先去掉k个物品i,再加回来k个物品i

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

暴力dp

#include <iostream>using namespace std;
const int N = 1010;
int f[N][N],v[N], w[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) {for (int k = 0; k * v[i] <= j; ++k) {f[i][j] = max(f[i][j],f[i - 1][j - k * v[i]] + k * w[i]);// cout << f[i][j];}}}cout << f[n][m];return 0;
}

我们可以发现

f[i,j]=Max(f[i-1,j],f[i-1,j-v]+w,f[i-1.j-2v]+2w,...,f[i-1.j-kv]+kw

f[i,j-v]=Max( f[i-1,j-v],f[i-1.j-2v]+w,...,f[i-1.j-kv]+(k-1)w

代码

#include <iostream>
// #include <algorithm>
using namespace std;
const int N = 1010;
int f[N][N],v[N], w[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][j-v[i]] + w[i]);           }}cout << f[n][m];return 0;
}

一维代码

#include <iostream>
// #include <algorithm>
using namespace std;
const int N = 1010;
int f[N],v[N], w[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 = v[i]; j <= m; ++j) {// f[i][j] = f[i-1][j];f[j] = max(f[j], f[j-v[i]] + w[i]);           }}cout << f[m];return 0;
}

多重背包问题

动态规划

  • 状态表示 f[i][j]
    • 集合:所有考虑前i个物品,且体积不大于j的全部选法
    • 属性:Max
  • 状态计算:集合的划分

题目描述

有 N 种物品和一个容量是 V 的背包。

第 i种物品最多有 sis_isi 件,每件体积是 viv_ivi ,价值是 wiw_iwi

求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。
输出最大价值。

输入格式

第一行两个整数,N,V,用空格隔开,分别表示物品种数和背包容积。

接下来有 N 行,每行三个整数 viv_ivi, wiw_iwi, sis_isi ,用空格隔开,分别表示第 i种物品的体积、价值和数量。

输出格式

输出一个整数,表示最大价值。

数据范围

0<N,V≤100
0<viv_ivi, wiw_iwi, sis_isi ≤100

输入样例
4 5
1 2 3
2 4 1
3 4 3
4 5 2
输出样例:
10

代码

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

当数据范围扩大

数据范围

0<N≤1000

0<V≤2000

0<viv_ivi, wiw_iwi, sis_isi ≤2000

f(i, j) = Max(f(i-1,j),f(i-1,j-v)+w,f(i-1,j-2v)+2w+...+f(i-1,j-sv)+sw)
f(i, j-v) = Max(f(i-1,j-v),f(i-1,j-2v)+w,f(i-1,j-3v)+2w+...+f(i-1,j-sv)+(s-1)w,f(i, j) = Max(f(i-1,j),f(i-1,j-v)+w,f(i-1,j-2v)+2w+...+f(i-1,j-(s+1)v)+sw)

所以不能用完全背包问题解决

我们可以采用二进制优化+01背包问题的方法

二进制优化

给出一堆苹果和10个箱子,选出n个苹果。将这一堆苹果分别按照1,2,4,8,16,…512分到10个箱子里,那么由于任何一个数字x∈[0,1023] (第11个箱子才能取到1024,评论区有讨论这个)都可以从这10个箱子里的苹果数量表示出来,但是这样选择的次数就是 ≤10次

代码

#include <iostream>
using namespace std;
const int N = 1e5 + 10;
int v[N], w[N];
int f[2020];
int main() {int n, m;cin >> n >> m;int cnt = 0;while (n--) {int a, b, s;cin >> a >> b >> s;int k = 1;while (k <= s) {v[++cnt] = a * k;w[cnt] = b * k;s -= k;k *= 2;}if (s){v[++cnt] = a * s;w[cnt] = b * s;}}n = cnt;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;
}

分组背包问题

有 N 组物品和一个容量是 V的背包。

每组物品有若干个,同一组内的物品最多只能选一个。
每件物品的体积是vi,jv_{i,j}vi,j,价值是wi,jw_{i,j}wi,j,其中 i 是组号,j 是组内编号。

求解将哪些物品装入背包,可使物品总体积不超过背包容量,且总价值最大。

输出最大价值。

输入格式

第一行有两个整数 N,V,用空格隔开,分别表示物品组数和背包容量。

接下来有 N 组数据:

  • 每组数据第一行有一个整数 SiS_{i}Si,表示第 i 个物品组的物品数量;
  • 每组数据接下来有 SiS_{i}Si 行,每行有两个整数vi,jv_{i,j}vi,j,wi,jw_{i,j}wi,j,用空格隔开,分别表示第 i个物品组的第 j 个物品的体积和价值;
输出格式

输出一个整数,表示最大价值。

数据范围

0<N,V≤100
0<Si≤100
0<vi,jv_{i,j}vi,j,wi,jw_{i,j}wi,jj≤100

输入样例
3 5
2
1 2
2 4
1
3 4
1
4 5
输出样例:

8

代码

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

相关文章:

动态规划(Dynamic Programming)——背包问题

动态规划(Dynamic Programming) 背包问题 目录动态规划(Dynamic Programming)背包问题01背包问题输入格式输出格式数据范围输入样例输出样例&#xff1a;二维一维完全背包问题多重背包问题输入格式输出格式数据范围输入样例输出样例&#xff1a;数据范围二进制优化分组背包问题…...

JVM学习02:内存结构

JVM学习02&#xff1a;内存结构 1. 程序计数器 1.1、定义 Program Counter Register 程序计数器&#xff08;寄存器&#xff09; 作用&#xff1a;是记住下一条jvm指令的执行地址 特点&#xff1a; 是线程私有的不会存在内存溢出 1.2、作用 程序计数器物理上是由寄存器来实…...

6年软件测试经验,从我自己的角度理解自动化测试

接触了不少同行&#xff0c;由于他们之前一直做手工测试&#xff0c;现在很迫切希望做自动化测试&#xff0c;其中不乏工作5年以上的人。 本人从事软件自动化测试已经近6年&#xff0c;从server端到web端&#xff0c;从API到mobile&#xff0c;切身体会到自动化带来的好处与痛楚…...

三种方式查看linux终端terminal是否可以访问外网ping,curl,wget

方法1&#xff1a;ping注意不要用ping www.google.com.hk来验证&#xff0c;因为有墙&#xff0c;墙阻止了你接受网址发回的响应数据。即使你那啥过&#xff0c;浏览器都可以访问Google&#xff0c;terminal里面也是无法得到响应 百度在墙内&#xff0c;所以可以正常拿到响应信…...

【Call for papers】SIGCOMM-2023(CCF-A/计算机网络/2023年2月15日截稿)

ACM SIGCOMM is the flagship annual conference of the ACM Special Interest Group on Data Communication (SIGCOMM). ACM SIGCOMM 2023, the 37th edition of the conference series, will be held in New York City, US, September 10 - 14, 2023. 文章目录1.会议信息2.时…...

Chapter5:机器人感知

ROS1{\rm ROS1}ROS1的基础及应用&#xff0c;基于古月的课&#xff0c;各位可以去看&#xff0c;基于hawkbot{\rm hawkbot}hawkbot机器人进行实际操作。 ROS{\rm ROS}ROS版本&#xff1a;ROS1{\rm ROS1}ROS1的Melodic{\rm Melodic}Melodic&#xff1b;实际机器人&#xff1a;Ha…...

[acwing周赛复盘] 第 90 场周赛20230211 补

[acwing周赛复盘] 第 90 场周赛20230211 补 一、本周周赛总结二、 4806. 首字母大写1. 题目描述2. 思路分析3. 代码实现三、4807. 找数字1. 题目描述2. 思路分析3. 代码实现四、4808. 构造字符串1. 题目描述2. 思路分析3. 代码实现六、参考链接一、本周周赛总结 T1 模拟T2 模拟…...

数组

一、数组中重复的数字题目描述&#xff1a;在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的&#xff0c;但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如&#xff0c;如果输入长度为7的数组{2,3,1…...

MicroBlaze系列教程(4):AXI_UARTLITE的使用

文章目录 @[toc]AXI_UARTLITE简介MicroBlaze添加串口IP常用函数使用示例参考资料工程下载本文是Xilinx MicroBlaze系列教程的第4篇文章。 AXI_UARTLITE简介 axi_uartlite是Xilinx提供axi-lite接口的通用串口IP核,用AXI-Lite总线接口和用户进行交互,速度可以根据不同的芯片调…...

GO 中的 init 函数

前言 go 语言中有一个非常神奇的函数 init ,它可以在所有程序执行开始前被执行&#xff0c;并且每个 package 下面可以存在多个 init 函数&#xff0c;我们一起来看看这个奇怪的 init 函数。 init 特性 init 函数在 main 函数之前执行&#xff0c;并且是自动执行&#xff1b…...

使用C#编写k8s CRD Controller

本文项目地址&#xff1a;k8s-crd - Repos (azure.com)CRDCRD指的是Custom Resource Definition。开发者更多的关注k8s对于容器的编排与调度&#xff0c;这也是k8s最初惊艳开发者的地方。而k8s最具价值的地方是它提供了一套标准化、跨厂商的 API、结构和语义。k8s将它拥有的一切…...

Ansible---playbook剧本

目录 引言&#xff1a;什么是playbook&#xff1f; 一、Playbook 1.1、playbook中的核心元素 1.2、playbook中的基础组件 1.3、playbook格式说明 1.4、实例&#xff1a;httpd服务剧本 二、playbook中的模块 2.1、Templates 模块 2.2、tags 模块 2.3、Roles 模块 引言&…...

Delphi 中TImageCollection和TVirtualImageList 控件实现high-DPI

一、概述RAD Studio允许你通过使用TImageCollection组件和TVirtualImageList组件&#xff0c;在你的Windows VCL应用程序中包含缩放、高DPI、多分辨率的图像。这两个组件位于Windows 10面板中&#xff1a;注意&#xff1a;如果你使用FireMonkey进行跨平台应用&#xff0c;请看T…...

Ros中如何给UR5配置自定义工具 | 在Rviz中给UR5机器人装载定义工具 | UR5配置自定义末端执行器

前言 在学习和项目研究的过程中&#xff0c;我需要在Ur5e上装上工具&#xff0c;以对现实场景进行仿真。网上会有一些装载/配置现成的夹爪&#xff0c;例如Robotiq等。但和我们装载自定义工具的场景还有些差异&#xff0c;因此写一篇博客记录&#xff0c;可能有偏差。如果有问…...

数据库 delete 表数据后,磁盘空间为什么还是被一直占用?

插&#xff1a; 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 坚持不懈&#xff0c;越努力越幸运&#xff0c;大家一起学习鸭~~~ 最近有个上位机获取下位机上报数据的项目&#xff0c…...

docker-微服务篇

docker学习笔记1.docker简介1.1为什么会出现docker&#xff1f;1.2docker理念1.3虚拟机&#xff08;virtual machine&#xff09;1.4容器虚拟化技术1.5一次构建到处运行2.docker安装2.1前提条件2.2docker基本构成2.3docker安装步骤*2.4测试镜像3.docker常用命令3.1 启动docker3…...

图像优化篇

目录&#xff08;1&#xff09;矢量图&#xff08;2&#xff09;位图 2.1 分辨率2&#xff0c;图像格式格式选择建议&#xff1a;&#xff08;1&#xff09;矢量图 被定义为一个对象&#xff0c;包括颜色&#xff0c;大小&#xff0c;形状&#xff0c;以及屏幕位置等属性&…...

在surface go 2上安装ubuntu 20.04

在surface go 2上安装ubuntu 20.04 1.制作安装盘 下载ubuntu系统的iso文件 使用Rufus软件将u盘制作为ubuntu系统的安装盘 2.在surface go 2上操作 禁用快速启动 在 Windows 中&#xff0c;禁用“电源选项”中的“快速启动”>选择电源按钮的功能 禁用 Bitlocker 在 Wi…...

Java:SpringMVC的使用(1)

目录第一章、SpringMVC基本了解1.1 概述1.2 SpringMVC处理请求原理简图第二章、SpringMVC搭建框架1、搭建SpringMVC框架1.1 创建工程【web工程】1.2 导入jar包1.3 编写配置文件(1) web.xml注册DispatcherServlet(2) springmvc.xml(3) index.html1.4 编写请求处理器【Controller…...

自动化测试岗位求职简历编写规范+注意事项,让你的简历脱颖而出

目录 前言 1.个人信息 2.教育背景(写最高学历) 3.个人技能(按精通/掌握/熟练/了解层次来写) 4.工作经历 5.工作经验/项目经历 6.自我评价 总结 前言 挑选一个阅读舒适度不错的模板 HR和面试官看的简历多&#xff0c;都是快速阅读&#xff0c;舒适度特别重要&#xff1b…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

第7篇:中间件全链路监控与 SQL 性能分析实践

7.1 章节导读 在构建数据库中间件的过程中&#xff0c;可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中&#xff0c;必须做到&#xff1a; &#x1f50d; 追踪每一条 SQL 的生命周期&#xff08;从入口到数据库执行&#xff09;&#…...