栈的运用(单调栈)
单调栈是一种特殊的栈,特殊之处在于栈内的元素都保持一个单调性,可能为单调递增,也可能为单调递减。
模拟一个单调递增的单调栈
4 5 3
3 —>加入5 4 ---->加入3,为了维护单调性,从栈顶开始 ----> 3
1 3 弹出所有大于3的元素,弹出5,4;加入3 1
1
以上就是单调栈的基本操作
poj 2559
柱状图是由一些宽度相同的长方形下端对齐后横向排列得到的图形。现在有由n个宽度为1,高度分别为h1,h2,hn的长方形从左到右依次排列成柱状图。问里面包含的长方形的最大面积是多少。
n=7,h={2,1,4,5,1,3,3}
#include<stdio.h>
#include<algorithm>
#include<stack>
#define ll long long
using namespace std;
const int maxn=100000+5;
ll h[maxn],l[maxn],r[maxn];
stack<ll>st;
//ll st[maxn];
int n;
//solve函数为单调栈题目的核心代码
ll solve()
{
int t=0;
for(int i=0;i<n;i++){
while(t>0&&h[st.top()]>=h[i]){
t--;
st.pop();
}
if(t==0)
l[i]=0;
else
l[i]=st.top()+1;
st.push(i);t++;
}
t=0;
for(int i=n-1;i>=0;i--){
while(t>0&&h[st.top()]>=h[i]){
t--;
st.pop();
}
if(t==0)
r[i]=n-1;
else
r[i]=st.top()-1;
st.push(i);t++;
}
long long res=0;
for(int i=0;i<n;i++){
res=max(res,h[i]*(r[i]-l[i]+1));
}
return res;
}
int main()
{
while(scanf("%d",&n)!=EOF&&n){
for(int i=0;i<n;i++)
scanf("%lld",&h[i]);
h[n]=0;
printf("%lld\n",solve());
}
return 0;
}
类似题目 poj 3494 思路:矩阵将每一行都进行一次单调栈