单调队列学习
来源:互联网 发布:孙玉伯 知乎 编辑:程序博客网 时间:2024/06/01 09:41
单调队列就是一个维护递增或者递减元素的队列。
当一个新的元素出现的时候,判断它与队尾元素的大小,不满足则出队,直到满足。再把新的元素压入队列。
经典的例题是 poj2823.
给一个序列和m,问这个序列所有长度为m的区间最大,最小值是多少。
显然,如果暴力时间复杂度为O(N*m) 不超时就怪了。
这题要在维护单调队列是保存答案,时间复杂度o(n)。
开一个结构体存模拟队列,一个元素存值,一个存位置。当队列中的元素已经不再m的范围内是要出队列。这个方法看了http://blog.csdn.net/cabi_zgx/article/details/52701266。
#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;struct node{ int x,y;}v[1010000]; //x表示值,y表示位置 可以理解为下标int a[1010000],n,m,mx[1010000],mn[1010000];void getmin(){ int i,head=1,tail=0; for(i=1;i<m;i++) { while(head<=tail && v[tail].x>=a[i]) tail--; v[++tail].x=a[i],v[tail].y=i; } for(;i<=n;i++) { while(head<=tail && v[tail].x>=a[i]) tail--; v[++tail].x=a[i],v[tail].y=i; while(v[head].y<i-m+1) head++; mn[i-m+1]=v[head].x; }}void getmax() //最大值同最小值的道理,只不过是维护的是递减队列{ int i,head=1,tail=0; for(i=1;i<m;i++) { while(head<=tail && v[tail].x<=a[i]) tail--; v[++tail].x=a[i],v[tail].y=i; } for(;i<=n;i++) { while(head<=tail && v[tail].x<=a[i]) tail--; v[++tail].x=a[i],v[tail].y=i; while(v[head].y<i-m+1) head++; mx[i-m+1]=v[head].x; }}int main(){ int i,j; scanf("%d%d",&n,&m); for(i=1;i<=n;i++)scanf("%d",&a[i]); getmin(); getmax(); for(i=1;i<=n-m+1;i++) if(i==1)printf("%d",mn[i]); else printf(" %d",mn[i]); printf("\n"); for(i=1;i<=n-m+1;i++) if(i==1)printf("%d",mx[i]); else printf(" %d",mx[i]); printf("\n"); return 0;}
阅读全文
0 0
- 单调队列学习 PKU2823
- 单调队列学习
- 单调队列学习
- 单调队列学习小结
- 学习笔记:单调队列
- 单调队列 学习笔记
- 单调队列学习
- 单调队列的学习
- 单调队列学习笔记
- 单调队列的学习 pku2823
- Algorithm学习笔记 --- 单调队列
- 学习笔记:复习单调队列
- 单调队列或单调栈的学习及认识
- [HAOI2007]理想正方形-单调队列学习笔记
- |算法讨论|单调队列 学习笔记
- 单调栈 单调队列
- 单调队列
- 单调队列
- 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 (多重背包 动态规划)
- ACM训练日记—8月10日
- nlp中的LSTM学习
- Java反射
- Java web学习笔记之servlet技术
- 单调队列学习
- 编辑距离问题
- HDU 6103 Kirinriki【尺取法】【思维题】【好题】
- Oracl安装在Windows中
- js中的原型
- 详细了解步进电机的最大静转矩以及矩频特性
- Bomb Game
- 为什么存储过程比sql语句效率高?
- 深入理解Spring系列之八:常用的扩展接口