[题目传送门] 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(" "); 31 for(int i = 1 ; i <= n ; i++) printf("%d ", l[i]); printf(" "); 32 for(int i = 1 ; i <= n ; i++) printf("%d ", r[i]); printf(" "); 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 ", ans); 39 } 40 return 0; 41 }