Input
The input contains several test cases. Each test case describes a histogram and starts with an integer n, denoting the number of rectangles it is composed of. You may assume that 1<=n<=100000. Then follow n integers h1,...,hn, where 0<=hi<=1000000000. These numbers denote the heights of the rectangles of the histogram in left-to-right order. The width of each rectangle is 1. A zero follows the input for the last test case.Output
For each test case output on a single line the area of the largest rectangle in the specified histogram. Remember that this rectangle must be aligned at the common base line.Sample Input
7 2 1 4 5 1 3 3 4 1000 1000 1000 1000 0Sample Output
8 4000 题意:n个宽度为1,高度为h[i](1<=i<=n)组成的柱形图,求里面包含的长方形的最大面积; 思路:如果确定了长方形的左端点L和右端点R,那么最大可能高度就是min{h[i]|L<=i<R}(一般做题区间都是左闭右开,便于计算),时间复杂度O(n^3),考虑优化区间最小值,可以降为O(n^2),但仍然无法在规定时间内求出答案。 考虑换种思路假设面积最大的长方形的左端为L,右端为R,高度为H。如果h[L-1]>=H,那么左端点可以更新为L-1,从而得到更大的长方形,与假设矛盾,故h[L-1]<H。同理,h[R]<H,并且高度H=min{h[i]|L<=i<R}。 做法:我们可以固定h[i]向左右方向延伸,则可以定义两个单调栈:L[i]=(j<=i并且h[j-1]<h[i]的最大的j) R[i]=(j<i并且h[j]>h[i]的最小的j) 在计算L[i]时,首先,当栈顶的元素j满足h[j]>=h[i],则不断取出栈顶元素。若栈为空,则L[i]=0,若h[j]<h[i],则L[i]=j+1.然后把i压入栈中。 时间复杂度:由于栈的压入和弹出操作都是O(n)次,因此整个算法的时间复杂度为O(n)。对于R也可以用同样的方法计算。 代码: //输入 int n; int h[maxn]; int L[maxn],R[maxn]; int st[maxn];//栈 void solve(){ //计算L int top=0;//单调递减栈 for(int i=0;i<n;i++) { while(top&&h[st[top]]>=h[i]) top--;//加入i时,判断栈顶值是否满足>=h[i] L[i]=top==0?0:(st[top]+1); st[++top]=i; } //计算R int top=0;//倒序单调递减栈 for(int i=n-1;i>=0;i--) { while(top&&h[st[top]]>=h[i]) top--;//加入i时,判断栈顶值是否满足>=h[i] R[i]=top==0?n:st[top]; st[++top]=i; } long long res=0; for(int i=0;i<n;i++) res=max(res,(long long)h[i]*(R[i]-L[i])); printf("%lld\n",res); }