笔者大概看了一下单调队列对于DP的优化,故撰此文,望有帮助。

(dp还是推式子难啊qwq)

例题1.

题目大意:在n个数的序列中,选择数字,使得其连续不超过k个数,且和最大。

本题的方程相对好推:设dp[i][0/1]为到了第i个数,且第i个数不选/选的最大值。

则有转移:dp[i][0]=max(dp[i-1][0],dp[i-1][1])

dp[i][1]=max{dp[j][0]-sum[j]+sum[i]},i-k<=j<i

枚举j即可。

但是题目会这么让你水过吗?

发现会超时,优化不可避免。

仔细观察方程,考虑它的特殊性。

对于方程1,我们不便再多做什么。但是对于方程2,显然仍有优化余地。

我们将sum[i]提出来,得到:

dp[i][1]=max{dp[j][0]-sum[j]}+sum[i].

这个方程只与j有关,我们让max里面的最大就好了。

维护它,我们可以用堆,也可以用单调队列,线段树。

本文主要讲对于单调队列的优化。它可以保证O(n)的时间复杂度。

首先,我们明确一点,我们维护的队首元素最大。显然,队列中的数字要单调递减。

其次,我们要严格确保我们查询的区间,保证队列中没有没用的数字。

并且每次枚举到下一个数的时候,注意更新队列。

考虑何时更新更优:

首先,当这个数字不在需要的范围的时候,删除即可。

其次,对于新插入的数字,我们要从队尾插入,比较哪个值更优:

判断它们的“浪费情况”即可。

用q[]表示队列,s[]表示前缀和,则判断:

s[q[head]]-f[q[head]][0]>s[i]-f[i][0]&&head<=tail

如果符合的话,就把它删掉吧。因为队尾的元素所浪费的比新插入的值多,显然一定不如它优。

由此,我们已经保证了单调队列的稳定复杂度。

给出代码:

#include<cstdio>
#include<iostream>
using namespace std;
long long q[2000000],f[2000000][2];
long long n,k,s[2000000],a[2000000];
long long tail,head;
int main(){
scanf("%lld%lld",&n,&k);
for(int i=1;i<=n;++i){
scanf("%lld",&a[i]);
s[i]=s[i-1]+a[i];//sum
}
tail=head=1;//初始化
for(int i=1;i<=n;++i){
f[i][0]=max(f[i-1][0],f[i-1][1]);//对于不选i,只考虑前面两个即可
while(q[head]<i-k&&head<=tail)head++;//判断队头是否在所找区间内
f[i][1]=f[q[head]][0]-s[q[head]]+s[i];//取MAX转移
while(f[i][0]-s[i]>f[q[tail]][0]-s[q[tail]]&&head<=tail)tail--;
q[++tail]=i;//更新队尾,当队列有数且当前队尾若插入i不满足单调性时
//写成s[i]-f[i][0]<s[q[tail]]-f[q[tail]][0]也可以
//可以理解为选到i和队尾时,两者不选的奶牛的效率和相比较,显然浪费少的更优,不优的删除即可
}printf("%lld\n",max(f[n][0],f[n][1]));
return 0;
}

双倍经验:P2034

持续更新中。

【优化】单调队列与dp的更多相关文章

  1. 【题解】Cats Transport (斜率优化+单调队列)

    [题解]Cats Transport (斜率优化+单调队列) # When Who Problem Lang Verdict Time Memory 55331572 Jun/09/2019 19:1 ...

  2. BZOJ_1999_[Noip2007]Core树网的核_单调队列+树形DP

    BZOJ_1999_[Noip2007]Core树网的核_单调队列+树形DP Description 设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边带有正整数的权,我们称T ...

  3. 【刷题笔记】DP优化-单调队列优化

    单调队列优化 眼界极窄的ZZ之前甚至不会单调队列--(好丢人啊) 单调队列优化的常见情景: 转移可以转化成只需要确定一个维度,而且这个维度的取值范围在某个区间里 修剪草坪 这个题学长讲的好像是另外一个 ...

  4. BZOJ.1010.[HNOI2008]玩具装箱toy(DP 斜率优化/单调队列 决策单调性)

    题目链接 斜率优化 不说了 网上很多 这的比较详细->Click Here or Here //1700kb 60ms #include<cstdio> #include<cc ...

  5. 完美字符子串 单调队列预处理+DP线段树优化

    题意:有一个长度为n的字符串,每一位只会是p或j.你需要取出一个子串S(注意不是子序列),使得该子串不管是从左往右还是从右往左取,都保证每时每刻已取出的p的个数不小于j的个数.如果你的子串是最长的,那 ...

  6. [bzoj1010](HNOI2008)玩具装箱toy(动态规划+斜率优化+单调队列)

    Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有 的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1.. ...

  7. Luogu【P1725】琪露诺(单调队列,DP)

    本文是笔者第二篇解题报告.从现在开始,会将练的一些题发到博客上并归类到"解题报告"标签中. 琪露诺是这样一道题 这道题可以用纯DP做,但是据说会超时.(为什么?看起来过河这题比它数 ...

  8. 单调队列与DP

    算是一个总结吧! 先来一个模板: TYVJ 1305 最大子序和 题目描述 输入一个长度为n的整数序列,从中找出一段不超过M的连续子序列,使得整个序列的和最大. 例如 1,-3,5,1,-2,3 当m ...

  9. 单调队列+线性dp题Watching Fireworks is Fun (CF372C)

    一.Watching Fireworks is Fun(紫题) 题目:一个城镇有n个区域,从左到右1编号为n,每个区域之间距离1个单位距离节日中有m个烟火要放,给定放的地点ai,时间ti当时你在x,那 ...

随机推荐

  1. 微信小程序|小游戏

    [官]小游戏开发 https://developers.weixin.qq.com/minigame/dev/index.html 官网 https://mp.weixin.qq.com 做了4个微信 ...

  2. ios .framework动态库重签名

    真机上运行.framework时,如果报 dyld'dyld_fatal_error:dyld: Library not loaded: @rpath/XX.framework/XX Referenc ...

  3. Spine学习九 - 冰冻效果

    想象这样一个效果,一个人被冰霜攻击命中,然后这个人整个就被冰冻了,那么spine动画要如何实现这个效果呢? 1.首先需要一个Spine动画,这个动画应该是相对静止的,因为人物已经被冰冻了,那么这个人儿 ...

  4. C++STL complex吃书使用指南

    说在前面: complex即为复数 使用c++自带的complex类型,首先要有<complex>头文件,还要使用std命名空间 声明方式: complex <T> a:  声 ...

  5. HDOJ 1003

    动态规划一直AC不了竟然是因为一厢情愿的多加了一个#! printf("Case #%d:\n",count); --------------------------------- ...

  6. 用navicat进行身份验证连接出现cannot connect to Mongodb authentication failed

    用navicat进行身份验证连接出现cannot connect to Mongodb authentication failed. 解决办法: 1.打开mongoDB连接 win+r --cmd-- ...

  7. element.ui 自定义样式问题

    方法有很多种 自定义类名 <el-button class="search_button" @click="search">查询</el-bu ...

  8. dict字典,以及字典的一些基本应用

    dict表示方法: dict={}或d=dict() 1.字典的增:d['元素名']='元素值'.或d.setdefault('key','value') 2.字典的删:d.pop(key).或del ...

  9. Python实现GUI开发 PySide2&PyQt环境配置

    更新于2020-09-15 - 18:50:37 [前言] 关于Python开发GUI图形界面程序的问题,大概是19年十分困扰我,主要是没有经验以及缺乏高效简洁的视频或教学文档,导致在19年中秋前后花 ...

  10. 接口、RESTful规范、DRF

    接口 #接口:url连接,通过向链接发送不同的类型请求与参数得到相应的响应数据 #1.在视图书写处理请求的 视图函数 #2.在路由层为视图函数配置 url链接=>产生接口 #3.前台通过ajax ...