用雙端佇列實現單調佇列
阿新 • • 發佈:2019-01-10
單調佇列是指:佇列中元素之間的關係具有單調性,而且,隊首和隊尾都可以進行出隊操作,只有隊尾可以進行入隊操作。
以單調不減佇列為例:佇列內的元素(e1,e2,e3...en)存在(e1<=e2<=e3<=...<=en)的關係,所以隊首元素e1一定是最小的元素。與優先佇列不同的是,當有一個新的元素e入隊時,先要將隊尾的所有大於e的元素彈出,以保證單調性,再讓元素e入隊尾。
例如這樣一組數(1,3,2,1,5,6),進入單調不減佇列的過程如下:
1入隊,得到佇列(1);
3入隊,得到佇列(1,3);
2入隊,這時,隊尾的的元素3>2,將3從隊尾彈出,新的隊尾元素1<2,不用彈出,將2入隊,得到佇列(1,2);
1入隊,2>1,將2從隊尾彈出,得到佇列(1,1);
5入隊,得到佇列(1,1,5);
6入隊,得到佇列(1,1,5,6);
程式碼實現
這個程式碼是實現單調不遞減的佇列
#include<bits/stdc++.h> const int N=1e6+10; using namespace std; int a[N]; int main() { int n; while(~scanf("%d",&n)) { memset(a,0,sizeof(a)); int i; deque<int>num; for(i=1; i<=n; i++) { scanf("%d",&a[i]); } num.push_back(a[1]); int a1,a2; for(i=2; i<=n; i++) { if(!num.empty()) a1=num.back(); while(1) { if(a1<=a[i]||num.empty()) { num.push_back(a[i]); break; } else if(!num.empty()) { num.pop_back(); if(!num.empty()) a1=num.back();//3 } } } while(!num.empty()) { printf("%d ",num.front()); num.pop_front(); } printf("\n"); } return 0; }