hdu1506(dp减少重复计算)

可以算出以第i个值为高度的矩形可以向左延伸left[i],向右延伸right[i]的长度

那么答案便是 (left[i] + right[i] + 1) * a[i] 的最大值

关键left[i] 和right[i]的计算

如果a[i] > a[i-1]  ,  那么left[i] = 0

如果a[i] <=a[i-1],  那么left[i] = left[i-1] + 1,   但是位置i-1-left[i-1]-1及其往左的元素没有比较过,所以需要继续去比较

同理right[i]的计算也是一样的

 1 #pragma warning(disable:4996)
 2 #pragma comment(linker, "/STACK:1024000000,1024000000")
 3 #include <stdio.h>
 4 #include <string.h>
 5 #include <time.h>
 6 #include <math.h>
 7 #include <map>
 8 #include <set>
 9 #include <queue>
10 #include <stack>
11 #include <vector>
12 #include <bitset>
13 #include <algorithm>
14 #include <iostream>
15 #include <string>
16 #include <functional>
17 #include <unordered_map>
18 typedef __int64 LL;
19 const int INF = 999999999;
20 
21 const int N = 100000 + 10;
22 int a[N];
23 LL left[N], right[N];
24 int main()
25 {    
26     int n;
27     while (scanf("%d", &n), n)
28     {
29         for (int i = 1;i <= n;++i)
30         {
31             scanf("%d", &a[i]);
32         }
33         left[1] = right[n] = 0;
34         int l,r;
35         for (int i = 2;i <= n;++i)
36         {
37             l = i - 1;
38             left[i] = 0;
39             while (l>=1 && a[i] <= a[l])
40             {
41                 left[i] += left[l] + 1;
42                 l = l - left[l] - 1;
43             }
44         }
45         for (int i = n - 1;i >= 1;--i)
46         {
47             right[i] = 0;
48             r = i + 1;
49             while (r <= n && a[i] <= a[r])
50             {
51                 right[i] += right[r] + 1;
52                 r = r + right[r] + 1;
53             }
54         }
55         LL ans = 0;
56         for (int i = 1;i <= n;++i)
57         {
58             ans = std::max(ans, (left[i] + right[i] + 1)*a[i]);
59         }
60         printf("%I64d\n", ans);
61     }
62     return 0;
63 }

 

posted @ 2015-09-05 15:20  justPassBy  阅读(249)  评论(0编辑  收藏  举报