先了解一下单调队列:
很明显的具有单调性
分为单调递增和单调递减两种,简单点讲就是维护队头为最大值或者为最小值
(建议采用双向队列 比较好写)
具体步骤:(这个是单调递减)
如果队列非空且当前值比队尾元素大,不断删除比该值小的元素,否则直接队尾入队
while(!que.empty()&&ma[i]>que.back())
{
que.pop_back();
}
que.push_back(i);
单调队列的作用::
1):可以用来维护区间的单调性,用来解决最大或最小的问题
2):可以用来求一个序列里第一个大于或等于数x的数
可能还有不知道的地方,敬请指教
看个例题
题意::
求序列中每一个在其右边的第一个比它大的值,就是向右找寻第一个比他本身大的值,并且储存下来,没找到则得0。
思路:维护单调递减队列即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 const int maxn=1e5+5; 5 int ma[maxn]; 6 deque<int> que; 7 int c[maxn]; 8 int main() 9 { 10 int n; 11 scanf("%d",&n); 12 for(int i=1;i<=n;i++) 13 { 14 scanf("%d",&ma[i]); 15 } 16 for(int i=n;i>=1;i--) 17 { 18 while(!que.empty()&&ma[i]>=ma[que.back()]) 19 { 20 que.pop_back(); 21 } 22 if(que.empty()){ 23 c[i]=0; 24 } 25 else{ 26 c[i]=que.back(); 27 } 28 que.push_back(i); 29 } 30 for(int i=1;i<=n;i++){ 31 printf("%d\n",c[i]); 32 } 33 return 0; 34 }
再推荐大家可以练练手的题:(难度不分先后)
hdu3530 Subsequence 单调队列入门题
poj2559 Largest Rectangle in a Histogram
poj2823 Sliding Window
洛谷 P1714 切蛋糕 P2032 扫描 P1901 发射站