每周一算法:背包问题(三)多重背包

多重背包

N N N件物品和一个容量是 M M M的背包。第 i i i种物品最多有 s i s_i si件,每件的体积是 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, s i s_i si,用空格隔开,分别表示第 i i i 件物品的体积,价值和数量。

输出格式

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

样例 #1

样例输入 #1

4 5
1 2 3
2 4 1
3 4 3
4 5 2

样例输出 #1

10

提示

0 < N ≤ 1000 , 0 < M ≤ 2000 0<N≤1000,0<M\le2000 0<N1000,0<M2000

0 < v i , w i , s i ≤ 2000 0<v_i,w_i,s_i≤2000 0<vi,wi,si2000

算法思想

状态表示

多重背包的特点是第 i i i种物品最多有 s i s_i si件。仍可以采用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
  • 放入 s i s_i si件,此时背包的最大价值为前 i − 1 i-1 i1种物品,在背包容量为 j − s i × v i j-s_i\times v_i jsi×vi的情况下的最大价值 f [ i − 1 ] [ j − s i × v i ] + k × w i f[i-1][j-s_i\times v_i]+k\times w_i f[i1][jsi×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 ≤ s i 0\le k\le s_i 0ksi,并且 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件物品的数量 s i s_i si,时间复杂度为 O ( s i ) O(s_i) O(si)

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

代码实现

#include <iostream>
using namespace std;
const int N = 1010, M = 2010;
int f[N][N];
int main(){int n, m;cin >> n >> m;for(int i = 1; i <= n; i++){int v, w, s;cin >> v >> w >> s;for(int j = 0; j <= m; j++){for(int k = 0; k <= s && 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 − s × v ] + s × 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-s\times v]+s\times w\} f[i][j]=max{f[i1][j],f[i1][jv]+w,f[i1][j2×v]+2×w+...+f[i1][js×v]+s×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 − ( s + 1 ) × v ] + ( s + 1 ) × 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-(s+1)\times v]+(s+1)\times w\} f[i][jv]=max{f[i1][jv],f[i1][j2×v]+w,f[i1][j3×v]+2×w+...+f[i1][j(s+1)×v]+(s+1)×w}

f [ i ] [ j − v ] f[i][j - v] f[i][jv] f [ i ] [ j ] f[i][j] f[i][j]和对比可以发现,多了一项 f [ i − 1 ] [ j − ( s + 1 ) × v ] + ( s + 1 ) × w f[i-1][j-(s+1)\times v]+(s+1)\times w f[i1][j(s+1)×v]+(s+1)×w。如果计算出 f [ i ] [ j − v ] f[i][j - v] f[i][jv],那么是否能得到 f [ i ] [ j ] f[i][j] f[i][j]呢?举个栗子:

在这里插入图片描述

也就是说,知道前 s + 1 s+1 s+1项的最大值并不能计算出前 s s s项的最大值,因此不能采用完全背包的思想来优化多重背包。

二进制枚举

在计算状态的过程中,需要枚举第 i i i种物品的数量 [ 0 , s i ] [0,s_i] [0,si],这里采用一种更高效的枚举方式——二进制枚举。例如当 s i = 1023 s_i=1023 si=1023时,可以将第 i i i种物品“打包”为:

  • 0 0 0件一组
  • 1 1 1件一组
  • 2 2 2件一组
  • 4 4 4件一组
  • 512 512 512件一组

通过上述组与组之间的组合,可以表示出 [ 0 , 1023 ] [0,1023] [0,1023]之间的任意一个数。如果把每组物品看成是01背包中的一种物品(仅能选择一次),那么就相当于用 10 10 10个新物品来表示原来的第 i i i个物品,通过组合这 10 10 10个新物品就可以枚举出第 i i i个物品的全部方案。

时间复杂度

  • 状态数 n × m n\times m n×m
  • 通过上述思想,原来要枚举 s s s次,现在只需要枚举 l o g s logs logs

总的时间复杂的为 ( n × m × l o g s ) (n\times m\times logs) (n×m×logs)

代码实现

#include <iostream>
using namespace std;
const int N = 1010 * 12, M = 2010;
int v[N], w[N];
int f[M];
int main()
{int n, m, k = 0;cin >> n >> m;for(int i = 1; i <= n; i ++){int a, b, s;cin >> a >> b >> s;//二进制拆分for(int j = 1; j <= s; j *= 2){v[++ k] = j * a;w[k] = j * b;s -= j;}//拆分后还有剩余if(s) v[++ k] = s * a, w[k] = s * b;}n = k; //拆分后实际的物品数量//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;
}

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

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

相关文章

pytorch 模型量化quantization

pytorch 模型量化quantization 1.workflow1.1 PTQ1.2 QAT 2. demo2.1 构建resnet101_quantization模型2.2 PTQ2.3 QAT 参考文献 pytorch框架提供了三种量化方法&#xff0c;包括&#xff1a; Dynamic QuantizationPost-Training Static Quantization&#xff08;PTQ&#xff0…

DevOps搭建(三)-Git安装详细步骤

前面两篇文章我们讲了如何安装swappiness安装和虚拟机。这篇我们详细讲下如何安装Git。 1、YUM源更改为阿里云镜像源 1.1、备份CentOS-Base.repo 先备份原有的 CentOS-Base.repo 文件 sudo mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup…

OCR原理解析

目录 1.概述 2.应用场景 3.发展历史 4.基于传统算法的OCR技术原理 4.1 图像预处理 4.1.1 灰度化 4.1.2 二值化 4.1.3 去噪 4.1.4 倾斜检测与校正 4.1.4.2 轮廓矫正 4.1.5 透视矫正 4.2 版面分析 4.2.1 连通域检测文本 4.2.2 MSER检测文本 4.3 字符切割 4.3.1 连…

2022年全国大学生数据分析大赛医药电商销售数据分析求解全过程论文及程序

2022年全国大学生数据分析大赛 医药电商销售数据分析 原题再现&#xff1a; 问题背景   20 世纪 90 年代是电子数据交换时代&#xff0c;中国电子商务开始起步并初见雏形&#xff0c;随后 Web 技术爆炸式成长使电子商务处于蓬勃发展阶段&#xff0c;目前互联网信息碎片化以…

数组逆序重放

数组逆序重放的意思是将数组的元素逆序排列&#xff0c;然后重新放回原数组中。这个操作可以在很多编程语言中实现&#xff0c;例如Python、Java等。 下面是一个Python的示例代码&#xff0c;可以实现这个操作&#xff1a; def reverse_and_rearrange(arr): # 反转数组 …

git rebase冲突说明(base\remote\local概念说明)

主线日志及修改 $ git log master -p commit 31213fad6150b9899c7e6b27b245aaa69d2fdcff (master) Author: Date: Tue Nov 28 10:19:53 2023 08004diff --git a/123.txt b/123.txt index 294d779..a712711 100644 --- a/123.txtb/123.txt-1,3 1,4 123 4^Mcommit a77b518156…

分享几个电视颜色测试图形卡

介绍 本文分享几个常见的电视颜色测试图形卡和一段matlab程序&#xff0c;完成JPG转FPGA烧写文件&#xff0c;便于把彩色图片预装载到FPGA内。 电视颜色测试图形卡 一种专业检测电视显示效果的工具。它通常由一张卡片和一些色块组成&#xff0c;可以根据标准色彩空间和颜色渐…

Web安全漏洞分析-XSS(中)

随着互联网的迅猛发展&#xff0c;Web应用的普及程度也愈发广泛。然而&#xff0c;随之而来的是各种安全威胁的不断涌现&#xff0c;其中最为常见而危险的之一就是跨站脚本攻击&#xff08;Cross-Site Scripting&#xff0c;简称XSS&#xff09;。XSS攻击一直以来都是Web安全领…

版本依赖冲突问题排查过程记录

问题 开发平台在集成minio时&#xff0c;pom引入了sdk。 <dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.5.7</version> </dependency>在调用上传文件API时&#xff0c;控制台报错&…

如何开启Windows Server 2016 远端桌面

使用GUI 设定 服务器管理器–> 本地服务器–> 远端桌面 启用远端桌面 远端–> 允许远端连线至此电脑 会提示防火墙设定跟电源设定 防火墙之前已经关闭了 完成

fpga rom 初始化文件的一些心得

目录 可能遇到的问题 问题 解决方案 rom的初始化 用途 文件类型 如何生成初始化文件 示例 Altera Xilinx 可能遇到的问题 问题 altera FPGA的rom找不到初始化文件&#xff0c;编译过程会提示类似的问题 Error(127001): Cant find Memory Initialization File or He…

Google Earth Engine谷歌地球引擎计算多年中某两个时间点之间遥感数据差值的平均值

本文介绍在谷歌地球引擎GEE中&#xff0c;提取、计算某一种遥感影像产品在连续的多年中&#xff0c;2个不同时相的数据差值的多年平均值&#xff0c;并将计算得到的这一景差值的结果图像导出的方法。 本文是谷歌地球引擎&#xff08;Google Earth Engine&#xff0c;GEE&#x…

R语言单因素方差分析+差异显著字母法标注+逐行详细解释

R语言单因素方差分析 代码如下 df <- read.csv("data.csv",header TRUE,row.names 1) library(reshape2) df <- melt(df,idc()) names(df) <- c(trt, val) df aov1 <- aov(val~trt,datadf) summary(aov1)library(agricolae) data <- LSD.test(aov…

harmonyOS学习笔记之stateStyles

stateStyles:多态样式 stateStyles可以依据组件的内部状态的不同,设置不同的样式 stateStyles是属性方法,可以根据状态来设置样式,类似于css伪类,但是语法不一样,ArkUI提供了四种状态: focused:获焦态 normal:正常态 pressed:按压态 disable:不可用态例如: Entry Component …

NAND Flash和NOR Flash的异同

NAND Flash和NOR Flash是两种常见的闪存类型。 NOR Flash是Intel于1988年首先开发出来的存储技术&#xff0c;改变了原先由EPROM和EEPROM一统天下的局面。 NAND Flash是东芝公司于1989年发布的存储结构&#xff0c;强调降低每比特的成本&#xff0c;更高的性能&#xff0c;并…

java企业财务管理系统springboot+jsp

1、基本内容 &#xff08;1&#xff09;搭建基础环境&#xff0c;下载JDK、开发工具eclipse/idea。 &#xff08;2&#xff09;通过HTML/CSS/JS搭建前端框架。 &#xff08;3&#xff09;下载MySql数据库&#xff0c;设计数据库表&#xff0c;用于存储系统数据。 &#xff08;4…

LeedCode刷题---子数组问题

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C/C》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、最大子数组和 题目链接&#xff1a;最大子数组和 题目描述 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连…

【计算机组成原理】存储器知识

目录 1、存储器分类 1.1、按存储介质分类 1.2、按存取方式分类 1.3、按信息的可改写性分类 1.4、按信息的可保存性分类 1.5、按功能和存取速度分类 2、存储器技术指标 2.1、存储容量 2.2、存取速度 3、存储系统层次结构 4、主存的基本结构 5、主存中数据的存放 5.…

浅学指针(5)sizeof和strlen的进阶理解

系列文章目录 文章目录 系列文章目录前言1. sizeof和strlen的对⽐1.1 sizeofsizeof不是函数&#xff0c;是运算符 1.2 strlen1.3 sizeof 和 strlen的对⽐ 2. 数组和指针笔试题解析• sizeof(数组名)&#xff0c;sizeof中单独放数组名&#xff0c;这⾥的数组名表⽰整个数组&…

MySQL 8.2 Command Line Client闪退

原因一 服务没有打开 原因二 找不到my.ini文件 原因一的解决方法 操作1进入管理 操作2选择服务 1 2 3 操作3选择MySQL服务并打开 原因二的解决方法 查找目录中是否有my.ini文件 C:\Program Files\MySQL\MySQL Server 8.2&#xff08;一般在这个目录下&#xff09; 有时…