HDU - 1506 - Largest Rectangle in a Histogram

先上题目:

Largest Rectangle in a Histogram

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 9826    Accepted Submission(s): 2717


Problem 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
 
  题意:给你一排等宽的篱笆(宽1单位),每一条木条的高度不一定相等,问能在这些篱笆上最大可以截取的平面面积是多大?
  以前遇见过这题,当时老师的解法是用了一个栈来辅助,不过感觉他的做法太复杂了→_→,这一题其实可以用简单的方法来做。定义两个数组l[MAX],r[MAX],分别表示对于某一个位置的木条i,从它开始向左(右)扫描,看看那有多少条木条的高度是大于等于i的高度,并把最远的木条的下标记录在l[i](r[i])里面,意思就是以它为矩形的一条边,高度作为矩形的宽,向左(右)最大可以截取多大面积的矩形,从一排木条截取多大面积的矩形,面积的大小取决的其中一个因素是木条的高度(矩形的宽),而高度一定是找最小的那个。
  这里需要先赋值l[i]=r[i]=i,然后考察l[i]的时候向左判断,因为左边的l[]已经考察过了,所以对于左边某条木条j的l[j],一定保存了j的考察结果,如果h[i]<=h[j],那么i还需要向左继续考察,下一个考察点就是l[j]保存的位置了。同理对于r[i]也一样。这样就可以减少很多不必要的比较了。
  对于以h[i]为宽的矩形的面积当然就是h[i]*(r[i]-l[i]+1)。
 
上代码:
 
 1 #include <cstdio>
 2 #include <cstring>
 3 #define max(x,y) (x > y ? x : y)
 4 #define MAX 100002
 5 #define LL long long
 6 using namespace std;
 7 
 8 LL h[MAX];
 9 int l[MAX],r[MAX];
10 
11 int main()
12 {
13     int n;
14     LL maxn;
15     //freopen("data.txt","r",stdin);
16     while(scanf("%d",&n),n){
17         for(int i=1;i<=n;i++){
18             scanf("%I64d",&h[i]);
19             l[i]=r[i]=i;
20         }
21         h[0]=h[n+1]=-1;
22         for(int i=2;i<=n;i++){
23             while(h[i]<=h[l[i]-1]){
24                 l[i]=l[l[i]-1];
25             }
26         }
27 
28         for(int i=n-1;i>0;i--){
29             while(h[i]<=h[r[i]+1]){
30                 r[i]=r[r[i]+1];
31             }
32         }
33         maxn=0;
34         for(int i=1;i<=n;i++){
35             LL s=h[i]*(r[i]-l[i]+1);
36             maxn=max(s,maxn);
37         }
38         printf("%I64d\n",maxn);
39     }
40     return 0;
41 }
1506

 

 
posted @ 2014-03-14 13:17  海拉鲁的林克  阅读(310)  评论(0编辑  收藏  举报