HDU 1506 Largest Rectangle in a Histogram

[题目传送门]  http://acm.hdu.edu.cn/showproblem.php?pid=1506 

[题目大意]

给定n个正整数,a[1] - a[n] 表示矩形的高 。 求一个区间,可以使拼接的矩形面积最大。a[i] 能和 a[i - 1] 或 a[i + 1] 能够拼接的条件为a[i - 1] >= a[i] 或 a[i + 1] >= a[i] 。

[分析]

枚举每一个位置矩形 i ,然后向左右拓展,直到拓展到一个矩形 j 的高小于矩形 i 。 这段长度,乘上矩形的高就为面积。

看数据范围后 发现不可行  n 最大有100000 .  思考递推方法 。

设置数组 l[]  和 r[] .  l[i] 表示矩形 i 能够向左拓展的个数, 同理 r[i] 是向右的,那么矩形 i 所在的大的矩形面积就是 a[i] * (l[i] + r[i] + 1).

递推 l[] ,对于矩形 i ,高度为  a[i] ,考虑 a[i] 和  a[i - 1] 。如果 a[i] > a[i - 1]  , 说明无法向左拓展 ,  l[i] = 0 。 若 a[i] <= a[i - 1] , 则可以证明a[i] 至少都小于 a[i - 1] 到 a[i - 1 - l[i - 1]] 。然后 a[i] 继续和 a[i - 1 - l[i - 1] - 1] 比较,继续这个过程。

同理r[].

[代码]

 1 #include <iostream>
 2 #include <cstdio>
 3 
 4 using namespace std;
 5 long long a[100010];
 6 long long l[100010];
 7 long long r[100010];
 8 
 9 int main(){
10     int n;
11     while(~scanf("%d",&n) && n){
12         a[0] = -1;
13         a[n + 1] = -1;
14         for(int i = 1 ; i <= n ; i++){
15             scanf("%lld",a + i);
16         }
17         for(int i = 1 ; i <= n ; i++){
18             int pos = i - 1;
19             int ans = 0;
20             while(pos > 0 && a[pos] >= a[i]){ans += (l[pos] + 1) ; pos = pos - l[pos] - 1;}
21             l[i] = ans;
22         }
23         for(int i = n ; i >= 1 ; i--){
24             int pos = i + 1;
25             int ans = 0;
26             while(pos <= n && a[pos] >= a[i]){ans += (r[pos] + 1) ; pos = pos + r[pos] + 1;}
27             r[i] = ans;
28         }
29         /*
30         for(int i = 1 ; i <= n ; i++) printf("%d ", a[i]); printf("\n");
31         for(int i = 1 ; i <= n ; i++) printf("%d ", l[i]); printf("\n");
32         for(int i = 1 ; i <= n ; i++) printf("%d ", r[i]); printf("\n");
33         */
34         long long ans = 0;
35         for(int i = 1 ; i <= n ; i++){
36             ans = max(ans , a[i] * (l[i] + r[i] + 1));
37         }
38         printf("%lld\n", ans);
39     }
40     return 0;
41 }

 

posted @ 2016-04-07 14:17  ACMZZ  阅读(198)  评论(0编辑  收藏  举报