Largest Rectangle in a Histogram(POJ No.2559) (栈的运用)

来源:互联网 发布:淘宝开店怎么找货源 编辑:程序博客网 时间:2024/06/06 16:25
A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rectangles have equal widths but may have different heights. For example, the figure on the left shows the histogram that consists of rectangles with the heights 2, 1, 4, 5, 1, 3, 3, measured in units where 1 is the width of the rectangles: 

Usually, histograms are used to represent discrete distributions, e.g., the frequencies of characters in texts. Note that the order of the rectangles, i.e., their heights, is important. Calculate the area of the largest rectangle in a histogram that is aligned at the common base line, too. The figure on the right shows the largest aligned rectangle for the depicted histogram.

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 integersh1,...,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 34 1000 1000 1000 10000

Sample Output

84000

题意: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);}


原创粉丝点击