POJ2823 滑动窗口 (单调队列)
2024-08-29 23:07:55
来学习一下单调队列:
他只可以从队尾入队,但可以从队尾或队首出队,来维护队列的单调性。单调队列有两种单调性:元素的值单调和元素的下标单调。
单调队列可以用来优化DP。状态转移方程形如dp[i]=min{dp[j]+f[j]},i-a<=j<=i-b。i增加1,j的上下界都增加1,即加入一个新的决策到候选集中,要把过时的决策剔除。当决策的取值范围的上下界均单调变化时,每个决策在候选集合中插入或删除最多一次,我们就可以用单调队列来优化。
回到这个题目:
用Min[i]和Max[i]表示以i结尾的大小为k的窗口中的最值。
以Min[i]为例,Min[i]=min{aj} ,i-k+1<=j<=i; i加1,j的上下界同时加1。Min用单调递增的队列维护。
(1)单调递增的队列,队头元素最小;
(2)待入队的元素<=队尾元素,队尾元素出队,直到满足单调性或队列为空,将此元素入队;
(3)队头元素下标<i-k+1,说明过时了,要删去。
1 #include<bits/stdc++.h>
2 using namespace std;
3 #define MAXN 1000010
4 int a[MAXN],Min[MAXN],Max[MAXN],Q[MAXN],n,k;
5
6 void get_min(){//求最小
7 int st=0,ed=0;
8 Q[ed++]=1;
9 Min[1]=a[1];
10 for(int i=2;i<=n;i++){
11 while(st<ed&&a[i]<a[Q[ed-1]]) ed--;//删除队尾元素
12 Q[ed++]=i;//插入队尾元素
13 while(st<ed&&Q[st]<i-k+1) st++;//删除队首过时元素
14 Min[i]=a[Q[st]];//此时答案就是队首元素
15 }
16 }
17
18 void get_max(){//求最大
19 int st=0,ed=0;
20 Q[ed++]=1;
21 Max[1]=a[1];
22 for(int i=2;i<=n;i++){
23 while(st<ed&&a[i]>a[Q[ed-1]]) ed--;
24 Q[ed++]=i;
25 while(st<ed&&Q[st]<i-k+1) st++;
26 Max[i]=a[Q[st]];
27 }
28 }
29
30 int main(){
31 scanf("%d%d",&n,&k);
32 for(int i=1;i<=n;i++) scanf("%d",&a[i]);
33 get_min();get_max();
34 for(int i=k;i<n;i++) cout<<Min[i]<<" "; cout<<Min[n]<<endl;
35 for(int i=k;i<n;i++) cout<<Max[i]<<" "; cout<<Max[n]<<endl;
36 return 0;
37 }
最新文章
- 【前端安全】JavaScript防http劫持与XSS
- blender 2.6 快捷键
- Linux C++ 调试神技--如何将Linux C++ 可执行文件逆向工程到Intel格式汇编
- SSH实例(7)
- java中的包装类与装箱拆箱定义
- 【Hibernate 9】悲观锁和乐观锁
- 【Stirling Number】
- Code First 更新数据库结构(简单实现方法:会删除原来的数据)
- LeetCode【第217题】Contains Duplicate
- (zz)Lambda 表达式(C# 编程指南)
- 基于Visual C++2013拆解世界五百强面试题--题4-double转换成字符串
- group by和order by的错误
- Chapter 16_0 面向对象编程
- CentOS yum换源
- Android IPC机制(三)使用AIDL实现跨进程方法调用
- centos7.4+openvpn-2.4.4+easy-rsa-3.0
- MySql Scaffolding an Existing Database in EF Core
- python标准库 - 数学库和随机数库
- 性能测试三十九:Jprofiler分析CPU过高和响应时间长的问题
- springmvc后台接前端的参数,数组,集合,复杂对象等