您的位置:首页 > Web前端

poj_2796 Feel Good(单调栈)

2017-02-13 12:59 465 查看
Feel Good
Time Limit: 3000MS Memory Limit: 65536K
Total Submissions: 13777 Accepted: 3831
Case Time Limit: 1000MS Special Judge
DescriptionBill is developing a new mathematical theory for human emotions. His recent investigations are dedicated to studying how good or bad days influent people's memories about some period of life.A new idea Bill has recently developed assigns a non-negative integer value to each day of human life.Bill calls this value the emotional value of the day. The greater the emotional value is, the better the daywas. Bill suggests that the value of some period of human life is proportional to the sum of the emotional values of the days in the given period, multipliedby the smallest emotional value of the day in it. This schema reflects that good on average period can be greatly spoiled by one very bad day.Now Bill is planning to investigate his own life and find the period of his life that had the greatest value. Help him to do so.InputThe first line of the input contains n - the number of days of Bill's life he is planning to investigate(1 <= n <= 100 000). The rest of the file contains n integer numbers a1, a2, ... an ranging from 0 to 106 - theemotional values of the days. Numbers are separated by spaces and/or line breaks.OutputPrint the greatest value of some period of Bill's life in the first line. And on the second line print two numbers l and r such that the period from l-th to r-th day of Bill's life(inclusive) has the greatest possible value. Ifthere are multiple periods with the greatest possible value,then print any one of them.Sample Input
6
3 1 6 4 5 2
Sample Output
60
3 5
跟poj2082好像没什么大的差别,poj2082求的是若干相邻长方形所组成的最大长方形,
也就是区间最小高乘区间总宽,而这道是求一个区间最小值与区间和的乘积最大,
同样是以数列中一个值为最小值然后左右延伸到出现比它小的值,从而得到一个区间。
用与做poj2082稍微不一样的方法做吧,用L[i],R[i]表示以val[i]为最小值所得到的区间
两端,然后区间和就能很直观地求出,那么问题就只有如何求L[i]和R[i]了,
可以维护一个单调递减栈求出。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <stack>#include <bitset>#include <queue>#include <set>#include <map>#include <string>#include <algorithm>#define FOP freopen("data.txt","r",stdin)#define FOP2 freopen("data1.txt","w",stdout)#define inf 0x3f3f3f3f#define maxn 100010#define mod 1000000007#define PI acos(-1.0)#define LL long longusing namespace std;int n;LL val[maxn], sum[maxn];int L[maxn], R[maxn];int sta[maxn];LL get_sum(int l, int r){return sum[r] - sum[l-1];}int main(){while(~scanf("%d", &n)){for(int i = 1; i <= n; i++) scanf("%lld", &val[i]), sum[i] = val[i];for(int i = 2; i <= n; i++) sum[i] += sum[i-1];int top = 0;for(int i = 1; i <= n; i++){while(top > 0 && val[sta[top]] >= val[i]) top--;L[i] = top == 0 ? 1 : sta[top]+1;sta[++top] = i;}top = 0;for(int i = n; i >= 1; i--){while(top > 0 && val[sta[top]] >= val[i]) top--;R[i] = top == 0 ? n : sta[top]-1;sta[++top] = i;}LL ans = -1, t;int ansi = 1;for(int i = 1; i <= n; i++){t = val[i] * get_sum(L[i], R[i]);if(ans < t) ans = t, ansi = i;}printf("%lld\n%d %d\n", ans, L[ansi], R[ansi]);}return 0;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: