题意:给定 n 个宽度为 1 的矩形组成的柱状图,求最大的矩形面积;
分析:单调栈维护两次
第一次从前到后维护当前小矩形高度h[i]左边第一个小于h[i]的位置,记作L[i];
第二次从后往前维护当前小矩形高度h[i]右边第一个小于h[i]的位置,记作R[i];
维护一个单调递增栈,当前高度若大于栈顶元素则直接压进去,否则不断弹出栈顶元素直到栈为空或者当前栈顶元素小于当前高度,再压进去,这样栈中的元素从前往后的高度是递增的且对应的小矩形下标也是递增的,所以栈中第二个元素对应的小矩形即第一个小于当前高度的小矩形;
代码:
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll;
const int N = 1E5+10;
int n,h[N];
int L[N],R[N];
int st[N];
int main()
{
while(~scanf("%d",&n)&&n){
for(int i=1;i<=n;i++) scanf("%d",&h[i]);
int cnt=0;
for(int i=1;i<=n;i++){
while(cnt>0&&h[st[cnt-1]]>=h[i]) cnt--;
L[i]=cnt==0?0:(st[cnt-1]);
st[cnt++]=i;
}
cnt=0;
for(int i=n;i>=1;i--){
while(cnt>0&&h[st[cnt-1]]>=h[i]) cnt--;
R[i]=cnt==0?n+1:(st[cnt-1]);
st[cnt++]=i;
}
ll ans=0;
for(int i=1;i<=n;i++){
ans=max(ans,(ll)(R[i]-L[i]-1)*h[i]);
}
printf("%lld\n",ans);
}
}