zoukankan      html  css  js  c++  java
  • 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];
     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         int top=0;
    13         for(int i=1; i<=n; ++i){
    14             l[i]=r[i]=i;
    15             while(top && a[stack[top]]>a[i]){
    16                 l[i]=l[stack[top]];
    17                 r[stack[top]]=i-1;
    18                 --top;
    19             }
    20             if(top && a[stack[top]]==a[i]) l[i]=l[stack[top]];
    21             stack[++top]=i;
    22         }
    23         int x,y;
    24         long long res=-1;
    25         for(int i=1; i<n; ++i){
    26             if(res<(s[r[i]]-s[l[i]-1])*a[i]){
    27                 res=(s[r[i]]-s[l[i]-1])*a[i];
    28                 x=l[i]; y=r[i];
    29             }
    30         }
    31         printf("%lld
    %d %d
    ",res,x,y);
    32     }
    33     return 0;
    34 }
  • 相关阅读:
    如何判断哪个方法调用了相同的事件?
    Windows Update问题
    Android学习笔记
    关于官方Reachability Demo理解
    poj 1797 Heavy Transportation
    poj 3013 Big Christmas Tree
    poj 1062 昂贵的聘礼
    poj 3615 Cow Hurdles(floyd)
    CF Planets(STL+ 最短路)
    poj 3026 Borg Maze
  • 原文地址:https://www.cnblogs.com/WABoss/p/5225379.html
Copyright © 2011-2022 走看看