题目链接:https://cn.vjudge.net/contest/313189#problem/I
翻译:
现有n个宽度为1,高度分别为h1,h2,h3,,,hn的长方形从左到右依次排列组成的柱状图。问里面包含的长方形的最大面积是多少?很直观的例子。
思路:
假设:面积最大的矩形的左端点为L,右端点为R,高为H=min{H(i)|L<=i<R}。(一个矩形的右端点等于下一个矩形的左端点)
if---->H(L-1)>=H,L可以更新为L-1,面积可以扩大,但这与假设矛盾,所以H(L-1)<H,同理可得,H®<H。
可以推出:
L[i]=(j<=i,并且H(j-1)<H(i)的最大j)
R[i]=(j>i,并且H(j)>H(i)的最小j)
计算:L[i]:
1.栈顶元素j满足H(j)>=H(i),不断弹出栈顶元素。
2.栈为空,L[i]=0;
3.若H(j)<H(i),则L[i]=j+1;
选上述符合的操作后,把i压入栈。
计算R[i]:
1.栈顶元素j满足H(j)>=H(i),不断弹出栈顶元素
2.栈为空,则L[i]=n;
3.H(j)<H(i),则L(i)=j;
选上述符合的操作后,把i压入栈
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAX_N 100005
int n,h[MAX_N];
int L[MAX_N],R[MAX_N],st[MAX_N];
void solve(){
int t=0;
for(int i=0; i<n; i++){
while(t>0&&h[st[t-1]]>=h[i])
t--;
L[i]=t==0?0:(st[t-1]+1);
st[t++]=i;
}
t=0;
for(int i=n-1; i>=0; i--){
while(t>0&&h[st[t-1]]>=h[i])
t--;
R[i]=t==0?n:st[t-1];
st[t++]=i;
}
long long ans=0;
for(int i=0; i<n; i++)
ans=max(ans,(long long)h[i]*(R[i]-L[i]));
printf("%lld\n",ans);
}
int main(){
while(~scanf("%d",&n)&&n){
for(int i=0; i<n; i++)
scanf("%d",&h[i]);
solve();
}
return 0;
}