简介
单调栈是一个数据结构,它的主要应用是在解决一些单调递增或单调递减的问题。
单调栈的基本思想是:如果一个序列是单调的(例如,递增或递减),那么可以用一个栈来模拟这个序列。栈顶元素始终表示当前序列的最大值或最小值。这样,我们就可以在 O(1) 时间内回答关于序列的一些问题。
具体实现上,单调栈可以有两种:单调递增栈和单调递减栈。
单调递增栈
在入栈时,始终选择当前序列中的最大值。这样,栈顶元素始终表示当前序列的最大值。对于查询“下一个比当前元素大的元素是什么”,直接返回栈顶元素即可。
单调递减栈
在入栈时,始终选择当前序列中的最小值。这样,栈顶元素始终表示当前序列的最小值。对于查询“下一个比当前元素小的元素是什么”,直接返回栈顶元素即可。
例题
找小的数字
给定一个序列,求每个元素左边最近的比它小的元素。
#include<bits/stdc++.h>
using namespace std;
int n,x;
stack<int> a;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&x);
while(!a.empty()&&a.top()>x){
a.pop();
}
if(a.empty()){
printf("-1 ");
}
else{
printf("%d ",a.top());
}
a.push(x);
}
return 0;
}
发射站
#include<bits/stdc++.h>
using namespace std;
int n,maxx,ans[1000005],h[1000005],v[1000005];
int main(){
scanf("%d",&n);
stack<int>a;
for(int i=1;i<=n;i++){
scanf("%d%d",&h[i],&v[i]);
}
for(int i=1;i<=n;i++){
while(!a.empty()&&h[a.top()]<h[i]){
ans[i]+=v[a.top()];
a.pop();
}
if(!a.empty()){
ans[a.top()]+=v[i];
}
a.push(i);
}
for(int i=1;i<=n;i++){
maxx=max(maxx,ans[i]);
}
printf("%d",maxx);
return 0;
}