您的位置:首页 > 其它

hdu1506(dp减少重复计算)

2015-09-05 15:20 393 查看
可以算出以第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]的计算也是一样的

#pragma warning(disable:4996)
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <bitset>
#include <algorithm>
#include <iostream>
#include <string>
#include <functional>
#include <unordered_map>
typedef __int64 LL;
const int INF = 999999999;

const int N = 100000 + 10;
int a
;
LL left
, right
;
int main()
{
int n;
while (scanf("%d", &n), n)
{
for (int i = 1;i <= n;++i)
{
scanf("%d", &a[i]);
}
left[1] = right
= 0;
int l,r;
for (int i = 2;i <= n;++i)
{
l = i - 1;
left[i] = 0;
while (l>=1 && a[i] <= a[l])
{
left[i] += left[l] + 1;
l = l - left[l] - 1;
}
}
for (int i = n - 1;i >= 1;--i)
{
right[i] = 0;
r = i + 1;
while (r <= n && a[i] <= a[r])
{
right[i] += right[r] + 1;
r = r + right[r] + 1;
}
}
LL ans = 0;
for (int i = 1;i <= n;++i)
{
ans = std::max(ans, (left[i] + right[i] + 1)*a[i]);
}
printf("%I64d\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: