每周一算法:背包问题(二)完全背包

完全背包

N N N件物品和一个容量是 M M M的背包。每种物品都有无限件可用。第 i i i件物品的体积是 v i v_i vi,价值是 w i w_i wi

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

输出最大价值。

输入格式

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

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

输出格式

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

样例 #1

样例输入 #1

4 5
1 2
2 4
3 4
4 5

样例输出 #1

10

提示

0 < N , M ≤ 1000 0<N,M≤1000 0<N,M1000

0 < v i , w i ≤ 1000 0<v_i,w_i≤1000 0<vi,wi1000

算法思想

状态表示

完全背包的特点是每种物品都有无限件可用。仍可以采用01背包的思想,将处理每种物品作为一个阶段,考虑在不同背包容量情况下的最大价值,将其状态定义为 f [ i ] [ j ] f[i][j] f[i][j],表示对于 i i i种物品,在背包容量为 j j j的情况下,背包获得的最大价值。

状态计算

在当前阶段,对于第 i i i种物品来说,有多种情况可以选择:

  • 放入 0 0 0件,此时的最大价值为前 i − 1 i-1 i1种物品,在背包容量为 j j j的情况下的最大价值 f [ i − 1 ] [ j ] f[i-1][j] f[i1][j]
  • 放入 1 1 1件,此时背包的最大价值为前 i − 1 i-1 i1种物品,在背包容量为 j − v i j-v_i jvi的情况下的最大价值 f [ i − 1 ] [ j − v i ] + w i f[i-1][j-v_i]+w_i f[i1][jvi]+wi
  • 放入 2 2 2件,此时背包的最大价值为前 i − 1 i-1 i1种物品,在背包容量为 j − 2 × v i j-2\times v_i j2×vi的情况下的最大价值 f [ i − 1 ] [ j − 2 × v i ] + 2 × w i f[i-1][j-2\times v_i]+2\times w_i f[i1][j2×vi]+2×wi
  • 放入 k k k件,此时背包的最大价值为前 i − 1 i-1 i1种物品,在背包容量为 j − k × v i j-k\times v_i jk×vi的情况下的最大价值 f [ i − 1 ] [ j − k × v i ] + k × w i f[i-1][j-k\times v_i]+k\times w_i f[i1][jk×vi]+k×wi

以上情况的前提是背包能够装得下 k k k件第 i i i种物品,也就是背包容量 j ≥ k × v i j\ge k\times v_i jk×vi。那么, f [ i ] [ j ] f[i][j] f[i][j]应该选择所有情况的最大值,即 f [ i ] [ j ] = max ⁡ { f [ i − 1 ] [ j − k × v i ] + k × w i } f[i][j] = \max\{f[i-1][j-k\times v_i]+k\times w_i\} f[i][j]=max{f[i1][jk×vi]+k×wi},其中 0 ≤ k 0\le k 0k,并且 k × v i ≤ j k\times v_i \le j k×vij

初始状态

f [ 0 ] [ 0 ] f[0][0] f[0][0]表示将前 0 0 0种物品装入容量为 0 0 0的背包中的产生的最大价值为 0 0 0

时间复杂度

  • 状态数 n × m n\times m n×m
  • 状态计算时需要枚举第 i i i件物品的数量 k k k,时间复杂度为 O ( m / v ) O(m/v) O(m/v)

总的时间复杂的为 O ( n × m 2 / v ) O(n\times m^2/v) O(n×m2/v)

代码实现

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

时空优化

根据上述状态转移方程,考虑能否直接用一维数组计算状态?

f [ i ] [ j ] = max ⁡ { f [ i − 1 ] [ j ] , f [ i − 1 ] [ j − v ] + w , f [ i − 1 ] [ j − 2 × v ] + 2 × w + . . . + f [ i − 1 ] [ j − k × v ] + k × w } f[i][j] = \max\{f[i-1][j], f[i-1][j-v]+w, f[i-1][j-2\times v]+2\times w+...+f[i-1][j-k\times v]+k\times w\} f[i][j]=max{f[i1][j],f[i1][jv]+w,f[i1][j2×v]+2×w+...+f[i1][jk×v]+k×w}

可得, f [ i ] [ j − v ] = max ⁡ { f [ i − 1 ] [ j − v ] , f [ i − 1 ] [ j − 2 × v ] + w , f [ i − 1 ] [ j − 3 × v ] + 2 × w + . . . + f [ i − 1 ] [ j − k × v ] + k × w } f[i][j - v] = \max\{f[i-1][j - v], f[i-1][j-2\times v]+w, f[i-1][j-3\times v]+2\times w+...+f[i-1][j-k\times v]+k\times w\} f[i][jv]=max{f[i1][jv],f[i1][j2×v]+w,f[i1][j3×v]+2×w+...+f[i1][jk×v]+k×w}

也就是说, f [ i ] [ j ] = max ⁡ { f [ i − 1 ] [ j ] , f [ i ] [ j − v ] + w } f[i][j] = \max\{f[i-1][j], f[i][j−v]+w\} f[i][j]=max{f[i1][j],f[i][jv]+w} f [ i ] [ j ] f[i][j] f[i][j]除了跟 f [ i − 1 ] [ j ] f[i-1][j] f[i1][j]有关,只与 f [ i ] [ j − v ] + w f[i][j−v]+w f[i][jv]+w有关。

此时将状态表示的二维数组压缩为一维后, f [ j ] = max ⁡ { f [ j ] , f [ j − v ] + w } f[j] = \max\{f[j], f[j−v]+w\} f[j]=max{f[j],f[jv]+w}。需要注意的是,这里 f [ j − v ] f[j−v] f[jv] i i i阶段的状态,由于 j − v ≤ v j-v\le v jvv,因此只需要从小到大枚举背包容量,就可以保证使用 i i i阶段的状态 f [ j − v ] ,来 f[j-v],来 f[jv],来计算 f [ j ] f[j] f[j]的最大值。这样不但可以将状态的二维数组优化为一维,也无需枚举第 i i i种物品的数量。

时间复杂度

  • 状态数 n × m n\times m n×m
  • 状态计算时间复杂度为 O ( 1 ) O(1) O(1)

总的时间复杂的为 ( n × m ) (n\times m) (n×m)

代码实现

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

相关练习

  • 疯狂的采药

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

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

相关文章

SAP_ABAP_RZ11解决SAP运行超时问题 TIME_OUT / rdisp/scheduler/prio_high/max_runtime

SAP ABAP 顾问&#xff08;开发工程师&#xff09;能力模型_Terry谈企业数字化的博客-CSDN博客文章浏览阅读510次。目标&#xff1a;基于对SAP abap 顾问能力模型的梳理&#xff0c;给一年左右经验的abaper 快速成长为三年经验提供超级燃料&#xff01;https://blog.csdn.net/j…

shell_80.Linux函数的递归

函数递归 局部函数变量的一个特性是自成体系&#xff08;self-containment&#xff09;。 除了获取函数参数&#xff0c;自成体系的函数不需要使用任何外部资源。 递归算法的经典例子是计算阶乘。一个数的阶乘是该数之前的所有数乘以该数的值。因此 要计算 5 的阶乘&#xff0c…

音频处理关键知识点

1 引言 现实生活中&#xff0c;我们听到的声音都是时间连续的&#xff0c;我们称为这种信号叫模拟信号。模拟信号需要进行数字化以后才能在计算机中使用。 目前我们在计算机上进行音频播放都需要依赖于音频文件。音频文件的生成过程是将声音信息采样、量化和编码产生的数字信号…

linux无网络 无ip,显示网络未连接

标题:linux无网络 无ip&#xff0c;显示网络未连接 参考blog&#xff1a;Linux无网络连接问题排查 首先我们发现ens33没有ip地址&#xff0c;说明这个接口并没有被分到ip&#xff1b; 我们可以通过手动方式来给ens33获得网络ip sudo dhclient ens33&#xff0c;之后再输入ifc…

FPGA UltraScale GTH 全网最细讲解,aurora 8b/10b编解码,HDMI视频传输,提供2套工程源码和技术支持

目录 1、前言免责声明 2、我这里已有的 GT 高速接口解决方案3、详细设计方案设计框图视频源选择ADV7611解码芯片配置及采集动态彩条视频数据组包UltraScale GTH 全网最细解读UltraScale GTH 基本结构参考时钟的选择和分配UltraScale GTH 发送和接收处理流程UltraScale GTH 发送…

【小沐学Python】Python实现Web服务器(Flask+celery,生产者-消费者)

文章目录 1、简介2、安装和下载2.1 flask2.2 celery2.3 redis 3、功能开发3.1 创建异步任务的方法3.1.1 使用默认的参数3.1.2 指定相关参数3.1.3 自定义Task基类 3.2 调用异步任务的方法3.2.1 app.send_task3.2.2 Task.delay3.2.3 Task.apply_async 3.3 获取任务结果和状态 4、…

web前端之JavaScript实现数据的流式获取、一边传输一边解析、fetch、getReader、TextDecoder、read、decode

MENU 前言代码TextDecodergetReaderfetch 前言 1、此功能类似于GTP一样一点一点的解析数据&#xff0c;不需要等到所有数据都返回才解析&#xff0c;这个是回来多少解析多少。 2、代码中的url是真实的URL&#xff0c;只是读取的是列表&#xff0c;所以流式的效果不是很明显&…

C++ priority_queue

一、简介 Priority Queue&#xff08;优先队列&#xff09; 是一种常用的数据结构&#xff0c;它基于每个元素关联的优先级而组织元素&#xff0c;确保高优先级的元素先被处理。在实际应用中&#xff0c;优先队列常用于解决与优先级相关的问题&#xff0c;如任务调度、图算法等…

2312skia,16画布

创建SkCanvas 首先,阅读SkCanvasAPI概述. Skia有多个接收SkCanvas绘图命令的后端.每个后端都有创建SkCanvas的独特方式.本页给出了每个示例: 光栅化 光栅化后端将绘画到可由Skia或客户管理的内存块. 推荐用管理画布命令要绘画内存对象的SkSurface为Raster和Ganesh后端创建画…

用CHAT如何写教研室工作总结?

问CHAT&#xff1a;写一份教研室工作总结 CHAT回复&#xff1a;以下是一个教研室工作总结的大纳&#xff0c;具体内容需要根据你们教研室的实际情况进行填充和修改。 教研室XXXX年度工作总结 1. 引言&#xff1a;简要介绍本年度工作总结的目的和主题。 2. 教育教学工作&…

Java核心知识点整理大全24-笔记

目录 22. 数据结构 22.1.1. 栈&#xff08;stack&#xff09; 22.1.2. 队列&#xff08;queue&#xff09; 22.1.3. 链表&#xff08;Link&#xff09; 22.1.4. 散列表&#xff08;Hash Table&#xff09; 22.1.5. 排序二叉树 22.1.5.1. 插入操作 22.1.5.2. 删除操作 2…

知识点滴 - 什么是半透膜和渗透压

半透膜和渗透作用 1748年的一天&#xff0c;法国物理学家诺勒为了改进酒的制作水平&#xff0c;设计了这样一个试验&#xff1a;在一个玻璃圆筒中装满酒精&#xff0c;用猪膀胱封住&#xff0c;然后把圆筒全部浸在水中。当他正要做下一步的工作时&#xff0c;突然发现&#xff…

DDOS攻击为何永不过时?

文章目录 一、DOS二、DDOS三、如何防范DDOS 1.可以过滤IP地址2.增加设备3.在骨干节点配置防火墙4.开启过滤5.配置DNS抗攻击6.白帽团队 四、白帽子 为什么二十年前中国红客们就在用的DDOS攻击直到现在还依然是黑客们最爱的攻击方法&#xff1f;二十年前的攻击技术为什么还不过…

Day12——集合

1.集合 在内存层面需要针对于多个数据进行存储。此时可以考虑的容器有&#xff1a;数组、集合类。 数组存储多个数据方面的特点&#xff1a; 数组一旦初始化&#xff0c;其长度就是确定的。数组中的多个元素是依次紧密排列的&#xff0c;有序的&#xff0c;可重复的。数组一…

mysql数据库常见函数(时间函数)

一、mysql日期函数 ADDDATE(d,n) &#xff1b; 计算起始日期 d 加上 n 天的日期 代码如下&#xff08;示例&#xff09;&#xff1a; SELECT ADDDATE("2023-11-11", INTERVAL 31 DAY); ->2023-12-12ADDTIME(t,n)&#xff1b; n 是一个时间表达式&#xff0c;时间…

基于Java SSM框架+Vue实现教学视频点播网站项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架Vue实现教学视频点播网站演示 摘要 随着现在网络的快速发展&#xff0c;网上管理系统也逐渐快速发展起来&#xff0c;网上管理模式很快融入到了许多学院的之中&#xff0c;随之就产生了“视频点播系统”&#xff0c;这样就让视频点播系统更加方便简单。 对于…

Java 学习之多态

多态的概念 多态 晚绑定。 所谓多态&#xff0c;就是父类型的引用可以指向子类型的对象&#xff0c;或者接口类型的引用可以指向实现该接口的类的实例。 不要把函数重载理解为多态。因为多态是一种运行期的行为&#xff0c;不是编译期的行为。 多态&#xff1a;父类型的引用可…

java源码-Java方法的定义和使用详解

1、 方法定义 如果我们想定义一个方法&#xff0c;基本语法如下&#xff1a; 修饰符&#xff1a;方法的修饰符是可选的&#xff0c;用于定义该方法的访问类型&#xff0c;可用的修饰符包括public/private/protected/默认的。 返回值&#xff1a;方法可以有返回值&#xff0c;…

线程中出现异常的处理

目录 前言 正文 1.线程出现异常的默认行为 2.使用 setUncaughtExceptionHandler() 方法进行异常处理 3.使用 setDefaultUncaughtExceptionHandler() 方法进行异常处理 4.线程组内处理异常 5.线程异常处理的优先性 总结 前言 在紧密交织的多线程环境中&#xff0c;异…

解决:ValueError: binary mode doesn‘t take an encoding argument

解决&#xff1a;ValueError: binary mode doesn‘t take an encoding argument 文章目录 解决&#xff1a;ValueError: binary mode doesn‘t take an encoding argument背景报错问题报错翻译报错位置代码报错原因解决方法方法一方法二今天的分享就到此结束了 背景 在使用之前…