单调队列の入门巩固

下方没有程序,只有过程~(因为懒

哪里有问题很正常,毕竟是个蒟蒻QAQ


1.判断序列连续区间,固定长度(为m)的最值。

问题描述:给定一个序列a,长度为n。现在需要找到区间长度为m的子区间的最大值/最小值,并依次输出。

洛谷P1886 滑动窗口https://www.luogu.com.cn/problem/P1886

我们就拿最大值举例:

比如1,3,4,2,1,0,7这一段序列,规定m=3

如果传统去枚举,每次遍历m个数。时间复杂度是O(nm),而单调队列却可以神奇的做到O(n)

单调队列是个什么东西呢??

一个For循环从1~n 

  • 发现队伍空的,把1入队。
  • 3比1大,把1踢走,发现前面没有数了,然后3入队。
  • 4比3大,把3踢走,发现前面没有数了,然后4入队。i>=m 输出队首:4
  • 2比4小,入队。i>=m 输出队首:4
  • 1比2小,入队。i>=m 输出队首:4
  • 0比1小,入队。发现队列长度太长了(len>m) 于是把队首弹出。i>=m 输出队首:2
  • 7比0大,把前面所有比他小的都踢走,再把队列长度不符合的踢走。于是输出队首:7

那么答案就是4 4 4 2 7

关键就是,我们始终是在维护一个单调(递减)的队列,并且是一个双端队列(需要从尾部入队/出队和头部出队)。

注意点:

  • 始终只有队尾入队
  • 手写双端队列会快一点
  • 什么时候队首出队,什么时候队尾出队分清(头出是因为长度过了,尾出是因为里面的数不满足现在要求了(他们太弱了需要离开了))
  • 该单调队列维护的是一个下标,不是实际的数字!!
  • 顺序可以是:尾部出队;入队;头部出队;做一些题目要做的;或者别的顺序

2.判断序列连续区间,不固定长度[S,T]是否存在一个性质。

里面需要二分答案转换一下,然后我们需要解决的问题就是:

给定一个序列a,长度为n。现在需要判断是否存在区间长度为len(len\epsilon [S,T])的连续子区间,使得该子区间的和>0

 洛谷p1419 寻找段落https://www.luogu.com.cn/problem/P1419

那么我们需要统计一段连续子区间的和,就可以变成前缀和的差值来实现。

由于我们是要让\large Sum(i)-Sum(k)越大越好,现在枚举的是i,也就是单调队列里面应该存的是\large Sum的最小值。

步骤如下:

  • 让尾部出队,并且入队:如果当前的\large Sum比尾部的小,我们就一直尾部出队。然后把这个\large Sum放进去。
  • 头部出队:由于我们的区间是[S,T],所以头部出队的时候就判断区间长度是不是大于T就可以了。
  • 判断性质:如果现在的\large Sum比队首(也就是最小值啦)要大,那就已经符合题目要求了。

完结撒花~

什么?你问我单调队列优化DP呢?

都说了蒟蒻,等我刷完基础DP再说吧~

QAQ

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值