• POJ


    从左向右扫,求得【1,i 】的最大子段和,1<=i<n
    从右向做扫,求得【 i,n】的最大子段和,1<i<=n
    然后 O(n) 枚举断点

    #include<cctype>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    typedef long long LL;
    const int N=1e5+5;
    const int inf=0x3f3f3f3f;
    int read()
    {
        int x=0,t=1;
        char ch=getchar();
        while(!isdigit(ch)){ if(ch=='-')t=-1; ch=getchar(); }
        while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); }
        return x*t;
    }
    int a[N],l[N],r[N];
    int main()
    {
        int n;
        while(scanf("%d",&n)==1&&n)
        {
            memset(l,0,sizeof(l) );
            memset(r,0,sizeof(r) );
            for(int i=1;i<=n;i++) a[i]=read();
            int sum=0;
            for(int i=1;i<=n;i++)
            {
                sum+=a[i];
                l[i]=max(l[i-1],sum);
                if(i==1) l[i]=sum;
                sum=max(sum,0);
            }
            sum=0;
            for(int i=n;i>0;i--)
            {
                sum+=a[i];
                r[i]=max(r[i+1],sum);
                r[i]=max(r[i+1],sum);
                r[i]=max(r[i+1],sum);
                if(i==n) r[i]=sum;
                sum=max(sum,0);
            }
            int ans=-inf;
            for(int i=1;i<n;i++)
                ans=max(l[i]+r[i+1],ans);
            printf("%d
    ",ans);
        }
        return 0;
    }
    /*
    7
    -20 5 -7 8 -4 5 -100
    4
    1 -2  -2 1
    3
    -1 -5 3
    */
    
    

    总结:以后遇到在区间上求两个不相交的子区间类似的问题,可以借鉴这道题的处理方法,从左到右、从右到左两次扫描,然后枚举断点!!!

  • 相关阅读:
    原来 是 需要的,
    传说中的 拉伸,
    date + 排序,
    两个 header,
    招财铃,负责模块,
    一个字母,
    一个词,
    vue+webpack静态资源路径引用
    Webstorm 的 Tab 键调整缩进值
    ES6常用语法
  • 原文地址:https://www.cnblogs.com/DeepJay/p/12025207.html
Copyright © 2020-2023  润新知