POJ - 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:

POJ - 2559_第1张图片
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, 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.

题目大意就是找出面积最大的矩形,一个很典型的单调栈问题。
因为习惯使用双向队列,下面的代码使用双向队列解决。
思路的话就是找出一个小矩形所属的最大的左右边界,因为每个高已经定了,所以只要找出最大的宽,就能得到含有这个小矩形的面积最大矩形。
例如
2 1 4 5 1 3 3
2的左边没有数字,所以2的左边界为0,然后将1放进队列,因为1比2小,并且已经知道了2的左边界,将2弹出,因为此时左边没有比1小的数,而且队列为空,所以1的左边界为0,下个数是4,而队列里面已经有1比4小,所以4的左边界为数字为1时数组的下标,然后到5,5跟4一样,之后就是1,因为5比1大,5不一定是1的左边界,所以把5弹出,一致到一个比1小的数才是1的左边界。
右边界的话,可以跟算左边界一样,将整个数组反过来计算。
下面是代码

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define INT_MINs -2000000000
#define INT_MAXs 2000000000
using namespace std;
typedef long long ll;
ll a[100005],lefts[100005],rights[100005];
dequeq;
int main()
{
    ll n;
    while(scanf("%lld",&n)&&n)
    {
        while(!q.empty())
            q.pop_back();
        ll i,j,MAX=-1;
        for(i=0;i=a[i])//队列中元素比要放进去的元素大,所以把队列中的元素弹出
                q.pop_back();
            if(q.empty())
                lefts[i]=0;
			else
                lefts[i]=q.back()+1;//队尾元素是比即将放进去的元素小的,所以这个元素的后一位才是放进去元素的左边界,要加一
			q.push_back(i);
        }
        while(!q.empty())
            q.pop_back();
        for(i=n-1;i>=0;i--)
        {
            while(!q.empty()&&a[q.back()]>=a[i])
                q.pop_back();
            if(q.empty())
                rights[i]=n;
			else
            rights[i]=q.back();
			q.push_back(i);
        }
        for(i=0;i

你可能感兴趣的:(POJ - 2559)