Largest Rectangle in a Histogram poj2259

版权声明:转载请带一下我这个小蒟蒻哦~ https://blog.csdn.net/QLU_minoz/article/details/89134247

 Largest Rectangle in a Histogram 

http://poj.org/problem?id=2559

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 integers h1,...,hn, where0<=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
0

Sample Output

8
4000

Hint

Huge input, scanf is recommended.

题意:柱状图是由一些宽度相等的长方形下端对齐后横向排列得到的图形,,现在有由n个宽度为1,高度分别为h1,h2,h3...hn的长方形从左到右依次排列组成的柱状图,问里面包含的长方形最大面积是多少?

训练赛做到这个题,经过队友提醒才知道是挑战程序设计上的原题(我实在是太弱惹QAQ)。如果确定当前的左端点和右端点来枚举的话,是O(n^3),实在是太慢辽。所以可以利用栈st[i] 来确定每个位置的可以到达的最远左端点L[i]和右端点R[i]。以当前位置i如果,栈顶的元素h[ st[t] ]>=h[i]的话,说明可以往左延展到这个位置那,就继续往左看t--,栈顶元素弹出,看下一个(也就是左边一个),直到不能延展到为止 。如果栈顶元素<h[i]的话,说明i这个点最左边就已经确定了,于是L[i]=st[i]+1。

如何来确定右端点呢?其实和确定左端点一样,只不过是从右边开始的,也就是如果确定左端点是正向的话,那确定右端点可以看成是逆序。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
const int maxn=1e5+5;
int h[maxn],st[maxn];//高度数组,栈数组
int L[maxn],R[maxn];
int main()
{
    int n;
    while(~scanf("%d",&n) && n)
    {
        for(int i=0;i<n;i++)
            scanf("%d",&h[i]);

        int t=0;//栈长度
        //L[i]  正向 当a[t]>=a[i] (栈内元素>=a[i])  pop
        for(int i=0;i<n;i++)
        {
            while(t>0&&h[i]<=h[st[t]])//栈内元素>=a[i]
                t--;
            L[i]=t?st[t]+1:0;
            st[++t]=i;
        }
        t=0;
        //R[i] 反向 当a[t]>=a[i] (栈内元素>=a[i])  pop
        for(int i=n-1;i>=0;i--)
        {
            while(t>0&&h[i]<=h[st[t]])//栈内元素>=a[i]
                t--;
            R[i]=t?st[t]:n;
            st[++t]=i;
        }

        ll Max=0;
        for(int i=0;i<n;i++)
            Max=max(Max,1ll*h[i]*(R[i]-L[i]));

        printf("%lld\n",Max);
    }
}

猜你喜欢

转载自blog.csdn.net/QLU_minoz/article/details/89134247