POJ2796 Feel Good(单调栈)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }

 

以上是关于POJ2796 Feel Good(单调栈)的主要内容,如果未能解决你的问题,请参考以下文章

POJ.2796feel good(单调栈)

POJ2796Feel Good[单调栈]

POJ2796:Feel Good单调栈

poj2796 feel good 单调栈

poj2796 feel good 单调栈

POJ 2796 Feel Good(单调栈)