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]的计算也是一样的
那么答案便是 (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; }
相关文章推荐
- IOS学习笔记1—Iphone程序运行流程
- 关于self.window.rootViewController的方法调用顺序
- 排序算法及其复杂度(JavaScript实现)
- Android 运行中效验文件完整合法性
- 如何减小在VS2013下生的exe文件的大小.
- Hive 1.1.1 启动错误
- Service绑定服务
- deque及迭代器失效问题
- 笔试真题解析 TT 研发工程师笔试卷
- effective c++ 尽量以const enum inline 替换 #define
- C语言怎么将用户账号密码写入文件实现登录注册功能?
- 一个IT人士的个人经历,给迷失方向的朋友
- C语言怎么将用户账号密码写入文件实现登录注册功能?
- iPhone第四节:UIDatePicker、UIPickerView
- 软肋
- VMware Ubuntu下找不到共享文件的解决方法
- 正则表达式
- C++中的虚基类
- 数据结构——堆
- UIWindow ,UIView