单调队列优化的背包问题

对于背包问题,经典的背包九讲已经讲的很明白了,本来就不打算写这方面问题了。

但是吧。

我发现,那个最出名的九讲竟然没写队列优化的背包。。。。

那我必须写一下咯嘿嘿,这么好的思想。

 

我们回顾一下背包问题吧。

 

01背包问题 


题目 
有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。 

这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。 

f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。则其状态转移方程便是:

f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}。 

就是说,对于本物品,我们选择拿或不拿

比如费用是3.

相关图解:

我们求表格中黄色部分,只和两个黑色部分有关

拿了,背包容量减少,我们价值加上减少后最大价值。

不拿,最大价值等于没有这件物品,背包不变,的最大价值。

完全背包问题 


题目 
有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。 


基本思路 
这个问题非常类似于01背包问题,所不同的是每种物品有无限件。

f[i][v]=max{f[i-1][v],f[i][v-c[i]]+w[i]}

图解:

因为我们拿了本物品还可以继续拿无限件,对于当前物品,无论之前拿没拿,还可以继续拿,所以是f[i][v-c[i]]+w[i]

 

换一个角度说明这个问题为什么可以f[i][v-c[i]]+w[i],也就是同一排。

其实是这样的,我们对于黄色部分,也就是当前物品,有很多种选择,可以拿一个,两个。。。一直到背包容量不够了。

也就是说,可以不拿,也就是J1,可以拿一个,也就是G1+w[i],也可以拿两个,也就是D1+2w[i],拿三个,A1+3w[i]。

但是我们看G2,G2其实已经是之前的最大了:A1+2w[i],D1+w[i],G1他们中最大的,对么?

既然G2是他们中最大的。

我们怎么求J2?

是不是只要求G2+w[i]和J1的最大值就好了。

因为G2把剩下的情况都保存好了。

 

多重背包问题 (正文)


题目 
有N种物品和一个容量为V的背包。第i种物品最多有n[i]件可用,每件费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。 

 

和之前的完全背包不同,这次,每件物品有最多拿n[i]件的限制。

思路一:我们可以把物品全都看成01背包:比如第i件,我们把它拆成n[i]件一样的单独物品即可。

思路二:思路一时间复杂度太高。利用二进制思路:一个n位二进制,能表示2^n种状态,如果这些状态就是拿了多少物品,我们可以把每一位代表的数都拿出来,比如n[i]=16,我们把它拆成1,2,4,8,1,每一堆物品看成一个单独物品。

为什么最后有个一?因为从0到16有十七种状态,四位不足以表示。我们最后补上第五位1.

把拆出来的物品按01背包做即可。

思路三:我们可以利用单调队列:

https://blog.csdn.net/hebtu666/article/details/82720880

再回想完全背包:为什么可以那么做?因为每件物品能拿无限件。所以可以。而多重背包因为有了最多拿多少的限制,我们就不敢直接从G2中拿数,因为G2可能是拿满了本物品以后才达到的状态 。

比如n[i]=2,如果G2的状态是2w[i],拿了两个2物品达到最大值,我们的J2就不能再拿本物品了。

如何解决这个问题?就是我给的网址中的,双端单调队列

利用窗口最大值的思想。

大家想想怎么实现再看下文。

 

发现问题了吗?

我们求出J2以后,按原来的做法,是该求K2的,但是K2所需要的信息和J2完全不同,红色才是K2可能需要的信息。

所以我们以物品重量为差,先把黑色系列推出来,再推红色系列,依此类推。

这个例子就是推三次,每组各元素之间差3.

这样就不会出现构造一堆单调队列的尴尬情况了。

在代码中继续详细解释:

//输入
int n;
int W;
int w[MAX_N];
int v[MAX_N];
int m[MAX_N];

 

int dp[MAX_N+1];//压空间,本知识参考https://blog.csdn.net/hebtu666/article/details/79964233
int deq[MAX_N+1];//双端队列,保存下标
int deqv[MAX_N+1];//双端队列,保存值

队列存的就是所有上一行能取到的范围,比如对于J2,队列里存的就是G1-w[i],D1-2w[i],A1-3w[i]等等合法情况。(为了操作方便都是j,利用差实现最终的运算)

他们之中最大的就是队头,加上最多存储个数就好。

 

 

 

void solve()
{for(int i=0;i<n;i++)//参考过那个网址第二题应该懂{for(int a=0;a<w[i];a++)//把每个分组都打一遍{int s=0;//初始化双端队列头尾int t=0;for(int j=0;j*w[i]+a<=W;j++)//每组第j个元素{int val=dp[j*w[i]+a]-j*v[i];while(s<t && deqv[t-1]<=val)//直到不改变单调性t--;deq[t]=j;deqv[t]=val;t++;//利用队头求出dpdp[j*w[i]+a]=deqv[s]+j*v[i];if(deq[s]==j-m[i])s++;//检查过期}}}
}

 

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

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

相关文章

用Python去除扫描型PDF中的水印

内容概述 含水印扫描型PDF文件&#xff0c;其中某页如下图所示&#xff0c;用Python去除其页顶及页底的水印。 处理思路&#xff1a;PDF中的每一页的水印的相对位置基本相同&#xff0c;将PDF每一页输出成图片&#xff0c;然后进行图片编辑&#xff0c;用白色填充方形覆盖水印…

二阶有源滤波器

滤波器是一种使用信号通过而同时抑制无用频率信号的电子装置, 在信息处理、数据传送和抑制干扰等自动控制、通信及其它电子系统中应用广泛。滤波一般可分为有源滤波和无源滤波, 有源滤波可以使幅频特性比较陡峭, 而无源滤波设计简单易行, 但幅频特性不如滤波器, 而且体积较大。…

用JS写了一个30分钟倒计时器

效果图 额外功能 左键单击计时器数字区&#xff0c;不显示或显示秒钟区。左键双击计时器数字区&#xff0c;暂停或启动计时器。计时完毕&#xff0c;只能刷新页面启动计时器。输入框可输入备注信息&#xff0c;输入框失去焦点或计时完毕后&#xff0c;时间戳附带备注信息会存入…

为什么高手离不了Linux系统?我想这就是理由!

通过本文来记录下我在Linux系统的学习经历&#xff0c;聊聊我为什么离不了Linux系统&#xff0c;同时也为那些想要尝试Linux而又有所顾忌的用户答疑解惑&#xff0c;下面将为你介绍我所喜欢的Linux系统&#xff0c;这里有一些你应该知道并为之自豪的事实。 这里你应该首先抛开W…

用JS写一个电影《黑客帝国》显示屏黑底绿字雨风格的唐诗欣赏器

效果图 放码过来 <!DOCTYPE HTML> <html><head><meta http-equiv"Content-Type" content"text/html;charsetutf-8"/><title>Black Screen And Green Characters</title><style type"text/css">table…

元器件封装大全:图解+文字详述

先图解如下&#xff1a; 元器件封装类型&#xff1a; A.Axial  轴状的封装&#xff08;电阻的封装&#xff09;AGP &#xff08;Accelerate raphical Port&#xff09; 加速图形接口 AMR(Audio/MODEM Riser) 声音/调制解调器插卡BBGA&#xff08;Ball Grid Array&#xff09;…

用JS写一个丐版《2048》小游戏

效果图 放马过来 <!DOCTYPE HTML> <html><head><meta http-equiv"Content-Type" content"text/html;charsetutf-8"/><title>2048</title><style type"text/css">.basic{height:80px;width:80px;back…

如何有效申请TI的免费样片

转自如何有效申请TI的免费样片 TI公司愿意为支持中国大学的师生们的教学、实验、创新实践、竞赛和科研项目&#xff0c;提供有限数量的免费样片。首先需要指出的是&#xff1a;所有的样片申请应该是诚实正当的&#xff0c;所有不恰当的申请&#xff08;包括不必要或多余的&…

用Python批量生成字幕图片用于视频剪辑

说明 视频剪辑时需要为视频添加字幕&#xff0c;添加字幕方法之一&#xff1a;根据字幕文本文件批量生成透明底只有字幕内容的图片文件&#xff0c;如下图&#xff0c;然后将这些图片文件添加到视频剪辑软件轨道中。 于是用pillow这Python图片工具库执行本次批量生成工作。 …

关于接地:数字地、模拟地、信号地、交流地、直流地、屏蔽地、浮

除了正确进行接地设计、安装,还要正确进行各种不同信号的接地处理。控制系统中&#xff0c;大致有以下几种地线&#xff1a; &#xff08;1&#xff09;数字地&#xff1a;也叫逻辑地&#xff0c;是各种开关量&#xff08;数字量&#xff09;信号的零电位。 &#xff08;2&…

AltiumDesigner中PCB如何添加 Logo

AltiumDesigner中PCB如何添加 Logo 转载2015-10-29 00:07:55标签&#xff1a;it文化教育首先用到的画图软件&#xff0c;当然是大家熟悉的Altium Designer了&#xff0c;呵呵&#xff0c;相信很多人都用过这款画图软件吧&#xff08;现在电路设计一直在用&#xff09;&#xff…

使用Ultra Librarian 生成PCB库文件

第一步&#xff1a;找到对应芯片的CAD文件&#xff0c;以OPA350为例&#xff1a; http://www.ti.com/product/opa350 第二步&#xff1a; 下载上图右边连接的 Ultra Librarian.zip &#xff0c; 然后根据提示&#xff0c;安装。 安装好后打开Ultra Librarian&#xff0c;会出现…

借汉诺塔理解栈与递归

我们先说&#xff0c;在一个函数中&#xff0c;调用另一个函数。 首先&#xff0c;要意识到&#xff0c;函数中的代码和平常所写代码一样&#xff0c;也都是要执行完的&#xff0c;只有执行完代码&#xff0c;或者遇到return&#xff0c;才会停止。 那么&#xff0c;我们在函…

qt超强绘图控件qwt - 安装及配置

qwt是一个基于LGPL版权协议的开源项目&#xff0c; 可生成各种统计图。它为具有技术专业背景的程序提供GUI组件和一组实用类&#xff0c;其目标是以基于2D方式的窗体部件来显示数据&#xff0c; 数据源以数值&#xff0c;数组或一组浮点数等方式提供&#xff0c; 输出方式可以是…

BFPRT

在一大堆数中求其前k大或前k小的问题&#xff0c;简称TOP-K问题。而目前解决TOP-K问题最有效的算法即是BFPRT算法&#xff0c;其又称为中位数的中位数算法&#xff0c;该算法由Blum、Floyd、Pratt、Rivest、Tarjan提出&#xff0c;最坏时间复杂度为O(n)O(n)。 读者要会快速排序…

HistCite 的使用方法

摘要 读文献自然要读精品&#xff0c;在面对一个陌生领域&#xff0c;如何才能以最快速度定位精品文献呢&#xff1f;本文将详细介绍 HistCite 的使用方法&#xff0c;结合 Web of Science 和 Endnote &#xff0c;演示如何在几个小时之内&#xff0c;对某个陌生领域的文献进行…

数据结构课上笔记7

介绍栈和队列基本概念和用法。 设输入序列1、2、3、4&#xff0c;则下述序列中&#xff08; &#xff09;不可能是出栈序列。【中科院中国科技大学2005】 A. 1、2、3、4 B. 4、 3、2、1 C. 1、3、4、2 D.&#xff14;、1、2、3 选…

ROC曲线与AUC值

ROC曲线与AUC值 1.概述AUC&#xff08;Area Under roc Curve&#xff09;是一种用来度量分类模型好坏的一个标准。这样的标准其实有很多&#xff0c;例如&#xff1a;大约10年前在machine learning文献中一统天下的标准&#xff1a;分类精度&#xff1b;在信息检索(IR)领域中常…

设置SSH免密码自动登录(使用别名)

每次登录服务器都要写一大串的用户名&#xff08;username服务器地址&#xff09;和登录密码十分的繁琐&#xff0c;所以本文就告诉大家如何通过修改配置文件&#xff0c;达到只需要输入&#xff1a;ssh jack(你起的别名)就可以一键登录到服务器中。 1.创建公钥&#xff08;相当…

串的定长表示

思想和代码都不难&#xff0c;和线性表也差不多&#xff0c;串本来就是数据受限的线性表。 串连接&#xff1a; #include <stdio.h> #include <string.h> //串的定长顺序存储表示 #define MAXSTRLEN 255 //用户可在255以内定义最大串长 typedef unsigned cha…