为了学习单调队列优化DP奔向了此题。。。

基础的多重背包就不展开了。设\(f_{i,j}\)为选前\(i\)个物品,重量不超过\(j\)的最大价值,\(w\)为重量,\(v\)为价值(蒟蒻有强迫症,特别不喜欢把\(v\)和\(w\)反着搞,\(weight\)和\(value\)嘛!),直接给转移方程

\[f_{i,j}=\max\{f_{i-1,j-kw_i}+kv_i\},k\in[0,min\{m,\lfloor \frac j{w_i}\rfloor\}]
\]

显然,\(f_i\)都是从\(f_{i-1}\)转过来的,所以第一维可以滚掉,得到每次转移的更简化的方程

\[f_j=\max\{f_{j-kw}+kv\}
\]

这样是\(O(nmW)\)的,还是要想办法优化。

众所周知,DP优化的根本原则是去掉无用的状态、利用重复转移的状态。可是这方程一眼根本看不出什么可优化的地方啊。。。。。。

我们要像这位Dalao一样善于发现,他的blog

所以,不管这个想法是怎么来的,我们先把\(j\)按模\(i\)意义下分组,设\(j=k_1w+d\),那么一组里的\(d\)都是同一个值。

然后方程就变成了这样

\[f_j=\max\{f_{k_1w+d-kw}+kv\}
\]

\[\qquad\qquad\quad=\max\{f_{(k_1-k)w+d}-(k_1-k)v\}+k_1v
\]

突然看到了\(k_1-k\)的重复出现!这也就意味着,在每一组中,有意义的状态只有\(\lfloor\frac{W-d}w\rfloor\)种!(\(W\)是最大载重)每次总的状态也就只有\(O(W)\)了。

设\(g_k=f_{kw+d}-kv\)。那么因为有\(m\)的限制,所以对于每个\(k_1\),我们需要且只能从\(max\{g_k|k\in[\max\{0,k_1-m\},k_1]\}\)转移。对于这样的转移,可以形象地和滑动窗口联系一下,相当于有一个宽度为\(m\)的窗口从一边一步步往另一边移动,每移一次都要取出窗口内的最大值。这个就上单调队列维护。

首先枚举\(d\)。接着,为了方便滚动,我们从大到小枚举\(k\)和\(k_1\),用一个单调队列维护下标在\([k_1-m,k_1]\)范围内的依次递减的若干个\(g\)值,因为显然如果有\(g_x\geq g_y,x<y\)的话\(g_y\)是没有用的。枚举\(k_1\)时,每次队首元素超出了范围就把它出队。用现在的队首更新\(f_j\)即\(f_{k_1w+d}\)。接着下一个元素\(g_{k_1-m-1}\)要入队了,把队尾\(g\)比这个小的全出队,再让它进来。最后输出\(f_W\)即可。

这样就是\(O(nW)\)的了,比二进制拆分难理解些但是更优秀了。

结合代码理解会更轻松哦

#include<cstdio>
#define RG register
#define R RG int
#define G c=getchar()
const int N=1e5+9;
int f[N],g[N],q[N];
inline int in(){
RG char G;
while(c<'-')G;
R x=c&15;G;
while(c>'-')x=x*10+(c&15),G;
return x;
}
inline int max(R x,R y){return x>y?x:y;}
inline void chkmx(R&x,R y){if(x<y)x=y;}
int main(){
R n=in(),maxw=in(),maxk,lim,v,w,m,d,i,k,k1,h,t,now;
for(i=1;i<=n;++i){
v=in();w=in();m=in();
for(d=0;d<w;++d){//枚举余数
maxk=(maxw-d)/w;lim=max(maxk-m,0);//先确定最初的范围
for(t=0,k=maxk-1;k>=lim;--k){//窗口先扩大宽度到m
now=f[k*w+d]-k*v;
while(t&&g[t]<=now)--t;//维护单调性
g[++t]=now;q[t]=k;
}
for(h=1,k1=maxk;~k1;--k1,--k){//可以开始转移了
if(h<=t&&q[h]>=k1)++h;//接着移动
if(h<=t)chkmx(f[k1*w+d],g[h]+k1*v);//转移
if(k<0)continue;//注意窗口可能已经出正数范围了
now=f[k*w+d]-k*v;
while(h<=t&&g[t]<=now)--t;//维护单调性
g[++t]=now;q[t]=k;
}
}
}
printf("%d\n",f[maxw]);
return 0;
}

洛谷P1776 宝物筛选_NOI导刊2010提高(02)(多重背包,单调队列)的更多相关文章

  1. 洛谷P1776 宝物筛选_NOI导刊2010提高(02)

    P1776 宝物筛选_NOI导刊2010提高(02) 题目描述 终于,破解了千年的难题.小FF找到了王室的宝物室,里面堆满了无数价值连城的宝物……这下小FF可发财了,嘎嘎.但是这里的宝物实在是太多了, ...

  2. P1776 宝物筛选_NOI导刊2010提高(02)&& 多重背包二进制优化

    多重背包, 要求 \(N\log N\) 复杂度 Solution 众所周和, \(1-N\) 之内的任何数可以由 \(2^{0}, 2^{1}, 2^{2} ... 2^{\log N}, N - ...

  3. P1776 宝物筛选_NOI导刊2010提高(02)

    题目描述 终于,破解了千年的难题.小FF找到了王室的宝物室,里面堆满了无数价值连城的宝物……这下小FF可发财了,嘎嘎.但是这里的宝物实在是太多了,小FF的采集车似乎装不下那么多宝物.看来小FF只能含泪 ...

  4. P1776 宝物筛选_NOI导刊2010提高(02)(背包的二进制优化)

    题目描述 终于,破解了千年的难题.小FF找到了王室的宝物室,里面堆满了无数价值连城的宝物……这下小FF可发财了,嘎嘎.但是这里的宝物实在是太多了,小FF的采集车似乎装不下那么多宝物.看来小FF只能含泪 ...

  5. Luogu P1776 宝物筛选_NOI导刊2010提高(02)(多重背包模版)

    传送门 多重背包板子题, 多重背包就是每种东西有好几个,可以把它拆分成一个一个的01背包 优化:二进制拆分(拆成1+2+4+8+16+...) 比如18=1+2+4+8+3,可以证明18以内的任何数都 ...

  6. luogu P1776 宝物筛选_NOI导刊2010提高(02)

    Sto flashhu orz flash太强啦 多重背包裸题(逃 使用压维大法,\(f_i\)为总重量为\(i\)时的答案 对于每种物品,记\(w\)为单个的重量,\(v\)为单个的价值,\(m\) ...

  7. 洛谷——P1795 无穷的序列_NOI导刊2010提高(05)

    P1795 无穷的序列_NOI导刊2010提高(05) 题目描述 有一个无穷序列如下: 110100100010000100000… 请你找出这个无穷序列中指定位置上的数字 输入输出格式 输入格式: ...

  8. 洛谷 P1795 无穷的序列_NOI导刊2010提高(05)

    P1795 无穷的序列_NOI导刊2010提高(05) 题目描述 有一个无穷序列如下: 110100100010000100000… 请你找出这个无穷序列中指定位置上的数字 输入输出格式 输入格式: ...

  9. 背包问题的优化(洛谷1776 宝物筛选_NOI导刊)

    背包型dp,但是没有看清数据范围差点认为是水题了,(然后诡异的拿了20分)标解是:2进制优化,比较简单把每一类物品看做若干个相互独立的物品,放在一个另外的数组里,然后全局跑一边01就可以.主要思想是: ...

随机推荐

  1. 数据库日志——mysql与Oracle的日志

    一.MySQL 在数据同步中用的比较多的是MySQL的binlog 1.bin-log简介 它记录了所有的DDL和DML(除了数据查询语句,select与show不记录)语句,以事件形式记录,还包含语 ...

  2. ASP.NET Core 登录失败。该登录名来自不受信任的域,不能与集成身份验证一起使用。

    原文:ASP.NET Core 登录失败.该登录名来自不受信任的域,不能与集成身份验证一起使用. 当进行数据迁移的时候提示 修改appsettings配置连接串的Trusted_Connection ...

  3. HDU3062&&HDU1814

    Preface 两道2-SAT模板题. HDU3062 看题目就一眼2-SAT.一对夫妻看成一个变量,之间的矛盾可以看成限制. 考虑不同席的限制,相当于选了\(i\)就不选\(j\),即必选\(j'\ ...

  4. .Net版本依赖之坑引发的搜查

    前言 今天上午,一个客户反馈XX消息没有推送到第三方链接.于是我查看了推送日志列表,并没有今天的.接着登录服务器查询文件日志,看到了记录.我们的代码步骤是消息先推送到消息队列,消费消息队列时,记录文件 ...

  5. Effective C++学习笔记之#define

    前言 条款02:尽量以const.enum.inline替换#define:尽可能用编译器代替不必要的预处理器. 内容 一.对于单纯常量 1.const 有两种特殊的const,常量指针和class专 ...

  6. [T-ARA][떠나지마][不要离开]

    歌词来源:http://music.163.com/#/song?id=22704408 잊기엔 너무 사랑했나봐 [id-ggi-en neo-mu sa-lang-haen-na-bwa] 아직도 ...

  7. Redis哨兵模式(sentinel)学习总结及部署记录(主从复制、读写分离、主从切换)

    Redis的集群方案大致有三种:1)redis cluster集群方案:2)master/slave主从方案:3)哨兵模式来进行主从替换以及故障恢复. 一.sentinel哨兵模式介绍Sentinel ...

  8. Linux系统下本地yum镜像源环境部署-完整记录

    之前介绍了Linux环境下本地yum源配置方法,不过这个是最简单最基础的配置,在yum安装的时候可能有些软件包不够齐全,下面说下完整yun镜像源系统环境部署记录(yum源更新脚本下载地址:https: ...

  9. Pairproject 移山之道 阅读随笔和一些问题

    首先不得不承认这本书的写作方式很独特,不像其他的计算机类的图书那样枯燥,让人读起来感觉很有意思,他也颠覆了我对计算机类图书的看法,这种写作方式值得我们学习. 先谈谈收获吧.读了两年大学,这是第一次写类 ...

  10. mybaits拦截器+自定义注解

    实现目的:为了存储了公共字典表主键的其他表在查询的时候不用关联查询(所以拦截位置位于mybaits语句查询得出结果集后) 项目环境 :springboot+mybaits 实现步骤:自定义注解——自定 ...