POJ 2796 Feel Good(单调栈)
2016-07-29 12:20
337 查看
题目链接:
POJ 2796 Feel Good
题意:
一个区间的权值是区间元素之和乘以区间最小的元素值。给一个长度为n的数组,求最大子区间权值。
数据范围:n≤106,data[i]∈[0,106]
分析:
考虑到每个数非负,只需要利用单调栈处理出每个数向左向右是最小值的最大区间就好了。
POJ 2796 Feel Good
题意:
一个区间的权值是区间元素之和乘以区间最小的元素值。给一个长度为n的数组,求最大子区间权值。
数据范围:n≤106,data[i]∈[0,106]
分析:
考虑到每个数非负,只需要利用单调栈处理出每个数向左向右是最小值的最大区间就好了。
#include <stdio.h> #include <string.h> #include <algorithm> #include <math.h> #include <climits> using namespace std; typedef long long ll; const int MAX_N = 100010; int n, top; int data[MAX_N], sta[MAX_N], L[MAX_N], R[MAX_N]; ll sum[MAX_N]; int main() { while (~scanf("%d", &n)) { sum[0] = 0; for (int i = 1; i <= n; ++i) { scanf("%d", &data[i]); sum[i] = sum[i - 1] + data[i]; } top = 0; //单调非递减栈 data[n + 1] = -1; for (int i = 1; i <= n + 1; ++i) { while (top && data[sta[top]] > data[i]) { R[sta[top]] = i - 1; --top; } if(top == 0) L[i] = 1; else L[i] = sta[top] + 1; sta[++top] = i; } ll ans = -1; int left, right; for (int i = 1; i <= n; ++i) { ll tmp = (sum[R[i]] - sum[L[i] - 1]) * data[i]; if (tmp > ans) { ans = tmp; left = L[i], right = R[i]; } } printf("%lld\n", ans); printf("%d %d\n", left, right); } return 0; }
相关文章推荐
- 浅谈单调队列、单调栈
- 初学ACM - 组合数学基础题目PKU 1833
- POJ ACM 1001
- POJ ACM 1002
- 1611:The Suspects
- POJ1089 区间合并
- POJ 2159 Ancient Cipher
- POJ 2635 The Embarrassed Cryptographe
- POJ 3292 Semi-prime H-numbers
- POJ 2773 HAPPY 2006
- POJ 3090 Visible Lattice Points
- POJ-2409-Let it Bead&&NYOJ-280-LK的项链
- POJ-1695-Magazine Delivery-dp
- POJ1523 SPF dfs
- POJ-1001 求高精度幂-大数乘法系列
- POJ-1003 Hangover
- POJ-1004 Financial Management
- [数论]poj2635__The Embarrassed Cryptographer
- [二分图匹配]poj2446__Chessboard
- POJ1050 最大子矩阵和