[关闭]
@Chilling 2017-03-02T18:25:17.000000Z 字数 2380 阅读 1177

POJ-2559: Largest Rectangle in a Histogram

单调栈&单调队列


链接:POJ-2559

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

Sample Output

8
4000

Hint

Huge input, scanf is recommended.

题意:给出几个连续的宽为1的木板的高度,求木板构成矩形的最大面积。

分析:将木板的长和宽(h,w)压入栈中,若下一个木板的高度大于等于当前栈顶的,那么依次弹出栈中的木板,并且累加他们的宽度,更新最大面积。

举例:(x,y)为一结构体,x表示矩形的高,y为矩形的宽。
给出的例子:7,2,1,4,5,1,3,3
(2,1)进栈;(2,1)
下一个高度为1,但是栈顶高度为2,大于1,说明高度为2的矩形不能延续到当前矩形,那么删除(2,1),累加宽度,并且更新最大面积,(1,2)进栈;(1,2)
(4,1)进栈;(1,2)(4,1)
(5,1)进栈;(1,2)(4,1)(5,1)
下一个高度为1,但是栈顶高度为5,大于1,那么删除(5,1),更新最大矩形面积5,把1累加到下一个元素,得到(4,2),仍然大于1,删除(4,2),更新最大矩形面积为8,把2累加到下一个元素,得到(1,4),面积为4小于8,不必更新,删除(1,4),把4累加到当前准备进栈的元素,(1,5)进栈;(1,5)
(3,1)进栈;(1,5)(3,1)
下一个高度为3,但是栈顶高度也为3,删除(3,1),不必更新,把1累加到当前准备进栈的元素,(3,2)进栈;(1,5)(3,2)
栈非空时,依次出栈;首先(3,2)出栈,不必更新,把2累加到下一个元素,当前栈为(1,7),(1,7)出栈,不必更新。
栈空,结束。
最后的答案就是8。


  1. #include<stdio.h>
  2. #include<stack>
  3. #define LL long long
  4. using namespace std;
  5. struct node
  6. {
  7. LL h,w;
  8. }a[100005];
  9. int main()
  10. {
  11. LL n;
  12. while(scanf("%lld",&n),n)
  13. {
  14. LL ans=0;
  15. for(int i=0;i<n;i++)
  16. {
  17. scanf("%lld",&a[i].h);
  18. a[i].w=1;
  19. }
  20. stack<node>q;
  21. for(int i=0;i<n;i++)
  22. {
  23. LL temp=0;
  24. while(!q.empty()&&q.top().h>=a[i].h)
  25. {
  26. LL x=q.top().h*(q.top().w+temp);
  27. ans=max(ans,x);
  28. temp+=q.top().w;
  29. q.pop();
  30. }
  31. node next;
  32. next.h=a[i].h;
  33. next.w=1+temp;
  34. q.push(next);
  35. }
  36. LL temp=0;
  37. while(!q.empty())
  38. {
  39. LL x=q.top().h*(q.top().w+temp);
  40. ans=max(ans,x);
  41. temp+=q.top().w;
  42. q.pop();
  43. }
  44. printf("%lld\n",ans);
  45. }
  46. return 0;
  47. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注