POJ2796 Feel Good(单调栈)

题意:给一个非负整数序列,求哪一段区间的权值最大,区间的权值=区间所有数的和×区间最小的数。

用单调非递减栈在O(n)计算出序列每个数作为最小值能向左和向右延伸到的位置,然后O(n)枚举每个数利用前缀和O(1)计算出以这个数为最小值能得到的最大的区间权。

以前写的单调栈,三个if分支,写得繁繁杂杂的;现在重写了一下,感觉代码简洁了不少:

 1 #include<cstdio>
 2 using namespace std;
 3 #define MAXN 111111
 4 int stack[MAXN],top;
 5 int l[MAXN],r[MAXN];
 6 long long a[MAXN],s[MAXN];
 7 int main(){
 8     int n;
 9     while(~scanf("%d",&n)){
10         for(int i=1; i<=n; ++i) scanf("%d",a+i),s[i]=s[i-1]+a[i];
11         a[++n]=-1;
12         for(int i=1; i<=n; ++i){
13             l[i]=r[i]=i;
14             while(top && a[stack[top]]>a[i]){
15                 l[i]=l[stack[top]];
16                 r[stack[top]]=i-1;
17                 --top;
18             }
19             if(top && a[stack[top]]==a[i]) l[i]=l[stack[top]];
20             stack[++top]=i;
21         }
22         int x,y;
23         long long res=-1;
24         for(int i=1; i<n; ++i){
25             if(res<(s[r[i]]-s[l[i]-1])*a[i]){
26                 res=(s[r[i]]-s[l[i]-1])*a[i];
27                 x=l[i]; y=r[i];
28             }
29         }
30         printf("%lld\n%d %d\n",res,x,y);
31     }
32     return 0;
33 }
时间: 2024-10-05 06:17:25

POJ2796 Feel Good(单调栈)的相关文章

poj2796 Feel Good 单调栈

题意:给定一个序列,需要找出某个子序列S使得Min(a[i])*Σa[i] (i属于S序列)最大 正解:单调栈 这题的暴力还是很好想的,只需3分钟的事就可以码完,以每个点拓展即可,但这样的复杂度是O(n^2)的,肯定会TLE 以暴力的思想作为基础,再进行深层次思考,考虑每个点往周围拓展的时候,都要走到最远的地方停下来,也就是说会有一个左上限,一个右上限(命名为:pre.next),不难发现再枚举5.4.3.2.1这个序列的时候,每次都要往左扫描到最左边,显然这是做了重复的事情,于是机智的我马上想

poj2796 维护区间栈//单调栈

http://poj.org/problem?id=2796 题意:给你一段区间,需要你求出(在这段区间之类的最小值*这段区间所有元素之和)的最大值...... 例如: 6 3 1 6 4 5 2 以4为最小值,向左右延伸,6 4 5  值为60....... 思路:解决完为这道题目,我才真正明白了单调栈的原理,它就是以某一个值为最小(最大)值,向这个值的两侧延伸,遇到大于它(小于它)的值,就将它延伸的范围扩大,当然,一般来说,要这样做的算法复杂度为o(n^2),但是借助栈这个玩意,维护其单调增

POJ2796(单调栈)

Feel Good Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 12987   Accepted: 3639 Case Time Limit: 1000MS   Special Judge Description Bill is developing a new mathematical theory for human emotions. His recent investigations are dedicated

UVA 1619/POJ2796 滑窗算法/维护一个单调栈

Feel Good Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 12409   Accepted: 3484 Case Time Limit: 1000MS   Special Judge Description Bill is developing a new mathematical theory for human emotions. His recent investigations are dedicated

51nod 1215 数组的宽度&amp;poj 2796 Feel Good(单调栈)

单调栈求每个数在哪些区间是最值的经典操作. 把数一个一个丢进单调栈,弹出的时候[st[top-1]+1,i-1]这段区间就是弹出的数为最值的区间. poj2796 弹出的时候更新答案即可 #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<algorithm> #include<queue> #include<cmath

学习笔记::单调栈

单调栈和单调队列长得不是很像. 单调栈的用处是求以一个元素为中心,向两边最多拓展多远距离. 两个小时就没了... poj2796 #include<cstdio> using namespace std; typedef long long ll; #define N 200010 struct data { ll v,sum,l,r; }x[N],st[N],ans; ll n; inline void read(ll&a) { ll x=0,f=1; char c=getchar(

POJ2796Feel Good[单调栈]

Feel Good Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 13376   Accepted: 3719 Case Time Limit: 1000MS   Special Judge Description Bill is developing a new mathematical theory for human emotions. His recent investigations are dedicated

POJ2796---Feel Good(前缀和+单调栈维护)

Description Bill 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

单调栈练习题题解

单调栈 单调栈顾名思义就是让栈中的元素是单调的,要么递增,要么递减.同样它也满足栈的性质,先进后出. 单调递增栈,则从栈顶到栈底的元素是严格递增的 单调递减栈,则从栈顶到栈底的元素是严格递减的 练习题 单调栈 练习题 POJ3250 POJ2796 BZOJ1113 HDU1506 POJ2559 JDFZ2997 POJ3250 POJ3250传送门 对于每一个牛来说,能看到的数目为向右数身高比它小的个数,累加就是答案. 所以可以倒着维护一个单调递增的栈,记录i之前的弹栈数目,累加. (正着也