单调队列入门(Jacob's zone)
来源:互联网 发布:寰宇人生软件下载 编辑:程序博客网 时间:2024/05/16 10:55
单调队列是从数列前扫到数列后...维护一个最值或者一个所需的最优解之类的...每次的最优解都是在队列的头....所以要一直维护队列..使其从头到尾都是单调的..要能保证如果当前头要出去了...后面的元素能马上顶上来作为头...
就拿POJ2823来举例....题目要求是给了一串n个数...从左到右每次框k个连续数..问每次框的数中最大数和最小数是什么..样例输入输出:
Sample Input
8 3 1 3
-1 -3 5 3 6 7
Sample Output
-1 -3 -3 -3 3 3
3 3 5 5 6 7
就拿样例说....准备一个队列...Myqueue...h代表队列头( 里面存的是下标不是数..为了是判断队首出列)..p代表队列尾..初始值h=1,p=0...就拿每次要一段最小值的队列变化过程来描述一下:
1、插入第1个数 Myqueue = { 1 } h=1; p=1 小于所给的框..还不需输出
2、插入第2个数 Myqueue= { 1 2 } h=1; p=2 ( 因为2号元素比1号元素大...先排到后面 ) 小于所给的框..还不需输出
3、插入第3个数 Myqueue= { 3 } h=1; p=1; ( 因为3号元素为-1比1号元素的1和2号元素的3都要小~~所以一直挤到最前面...1,2都出列 ) 输出 a[ Myqueue[h] ]的值 -1
4 、插入第4个数 Myqueue={ 4 } h=1; p=1; ( 因为4号元素比3号元素小....所以挤掉3号元素 ) 输出 a[ Myqueue[h] ]的值 -3
5、插入第5个数 Myqueue={ 4 5 } h=1; p=2 ( 因为5号元素比4号元素大...先排到后面 ) 输出 a[ Myqueue[h] ]的值 -3
6、插入第6个数 Myqueue={4 6 } h=1; p=2 ( 因为6号元素比5号元素小....但是又没有4号元素小..所以只能挤掉5号元素 ) 输出 a[ Myqueue[h] ]的值 -3
7、插入第7个数 Myqueue={ 6 7 } h=2; p=3 { 这里为什么4出列了?因为4到7已经不能被所给的范围框住了...所以4要出列..然后继续操作...因为7号元素比6号元素大...先排到后面) 输出 a[ Myqueue[h] ]的值 3
8、插入第8个数 Myqueue={6 7 8 } h=2; p=4; { 因为8号元素比7号元素和6号元素都要大...所以放到后面... ) 输出 a[ Myqueue[h] ]的值 3
还有一点要特别注意!!!如果后面的数和h[p]元素的数相等时...也要挤掉h[p]的....因为这个我WA了一次...囧....
这道题用单调队列来跑只要5000MS..的确快了不少..但看大牛们还能更快...想知道怎么做到的...
PS:...有个地方一定要注意...每次插入新数到队列都要从队尾往队首扫..扫到比自己小的就确定位置..扫到比自大的就把这个大的数给挤掉.....如果从前往后扫....例如
1 2 3 4 5 6 7 8 9 ..... 很长一列...要插入一个很大的数...从前一直遍历到最后面..才确定位置..这不是关键..关键是这一路过去..什么操作都没有做..白白扫了一大片空间...而从后往前扫...要么确定位置...要么踢到元素...总是在操作..所以必须要从后往前来判断并插入....
/* Title: POJ 2823 Author: RudyLu5 Date: 2012.02.28 Algorithm: Monotonous Queue License:GPL Night Gathers, and My Watch Begins, it shall Never End until My Death*/#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cmath>using namespace std;int n, k;int data[1000005];int myQueue[1000005];void Solve(){ int i, j, head = 1, rear = 0, t; myQueue[head] = 1; for(i = 1; i <= n; ++i) { if(i - myQueue[head] == k) head++; if(rear == head - 1 || data[i] > data[myQueue[rear]]) myQueue[++rear] = i; else { while(rear >= head && data[i] <= data[myQueue[rear]]) { myQueue[rear--] = i; } rear++; } if(i >= k) printf("%d ", data[myQueue[head]]); } printf("\n"); head = 1, rear = 0, myQueue[1] = 1; for(i = 1; i <= n; ++i) { if(i - myQueue[head] == k) head++; if(rear < head || data[i] < data[myQueue[rear]]) myQueue[++rear] = i; else { while(rear >= head && data[i] >= data[myQueue[rear]]) { myQueue[rear--]=i; } rear++; } if(i >= k) printf("%d ", data[myQueue[head]]); } printf("\n");}int main(){ int i; scanf("%d%d", &n, &k); for(i = 1; i <= n; ++i) { scanf("%d", &data[i]); } Solve(); return 0;}
- 单调队列入门(Jacob's zone)
- poj2823(单调队列入门)
- poj2823Sliding Window(单调队列入门)
- 单调队列(入门)
- 单调队列入门
- C++单调队列入门
- 单调队列入门
- HDU 4122--Alice's mooncake shop(单调队列)
- hdu 4123 Bob’s Race(树形DP+单调队列)
- 树形DP+RMQ+单调队列(Bob’s Race HDU4123)
- HDU 4123 Bob’s Race (树形DP + 单调队列)
- HDU 4123 Bob’s Race(树形DP + 单调队列)
- Largest Submatrix of All 1’s (单调队列)
- Largest Submatrix of All 1’s (单调队列)
- Largest Submatrix of All 1’s--(单调队列)
- FZU 1894 单调队列入门
- POJ2823 单调队列优化入门
- poj~2823(单调队列入门)
- 封装类、内部类、匿名类
- ssh超时断开的解决方法
- poj 2724 Purifying Machine 二分匹配
- 【容斥原理】HDU 4135
- 互联网大公司里的小团队化,会是公司组织的未来吗?
- 单调队列入门(Jacob's zone)
- 定义了重复的 system.web.extensions/scripting/scriptResourceHandler
- 对各种语言的看法
- 模拟实现c语言中的动态内存分配malloc函数
- final、String
- ssh端口修改
- 内存对齐
- HDU 1028
- dataGridView1_CellContentDoubleClick事件处理