您的位置:首页 > 其它

POJ 2559 Largest Rectangle in a Histogram(单调栈)

2016-09-22 12:42 507 查看
传送门

Description

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 follown 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
0

Sample Output

8
4000

Hint

Huge input, scanf is recommended.


思路

因为每个矩形的宽都为1,高不等,要求拼接起来的矩形的面积的最大值,可以看做给定一列数,定义子区间的值为区间长度乘以区间最小值,求区间值最大为多少。直接枚举肯定T,所以以每个值为区间最小值,向左向右扩展延伸区间,然后更新最大值,也就是单调栈的思想。如果当前元素大于栈顶元素,那么这个元素是不能向前伸展的;如果当前元素小于栈顶元素,这个时候就要把栈中的元素一个一个弹出来,直到当前元素大于栈顶元素,对于弹出来的元素,它扩展到当前元素就不能向后伸展下去了,因此对于弹出来的元素这个时候就可以计算左右端点形成区间与最小值的乘积了,维护一个最大值就好了。


#include<stdio.h>
#include<string.h>
typedef __int64 LL;
const int maxn = 100005;
LL a[maxn],stack[maxn],left[maxn];

int main()
{
int N;
while (~scanf("%d",&N) && N)
{
LL res = 0,tmp;
memset(stack,0,sizeof(stack));
memset(left,0,sizeof(left));
for (int i = 1;i <= N;i++)	scanf("%I64d",&a[i]);
a[++N] = -1;             //手动加上“-1”,使得所有元素都能入栈出栈
int top = 0;
for (int i = 1;i <= N;i++)
{
if (!top || a[i] > a[stack[top-1]])
{
stack[top++] = i;
left[i] = i;
continue;
}
if (a[i] == a[stack[top-1]])	continue;

while (top > 0 && a[i] < a[stack[top-1]])
{
top--;
tmp = a[stack[top]]*((i-1)- (left[stack[top]]-1));
res = res<tmp?tmp:res;
}
tmp = stack[top];
stack[top++] = i;
left[i] = left[tmp];
}
printf("%I64d\n",res);
}
return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: