Ring two largest sub-segment and

Step 1

First consider the case of a chain, which is the chain

++++++++-------------++++++++

The PS  :  + + represents a sub-segment using

A method can be considered to meet halfway with  g [i]  expressed in  I I ending line, and before the maximum sub-segment,

To  h [i]  expressed in  I I ending line, and after the maximum sub-segment

Then the answer is,  G [i] + H [i + 1]  (disjoint, so  +1  )

Step 2

If it is the ring?

+++---++++++----+++++++++++++++++

As the saying goesBeing the anti difficult, although I do not know how to deal with three sections, but it can not take the two, go with a reduced sum, you can get answers

Note that a pit

  1. If we do not take the head and tail, leaving only  1 1, obviously does not meet the conditions, so there is special sentenced to  1 case 1

Because of the presence of negative weights, so the time can not be set to 0 extremes, should be changed -inf

Step 3

#include<bits/stdc++.h>
using namespace std;
long long n,a[200005],f[200005],g[200005],b[200005],sum;
bool check(){//特判
    int cnt=0;
    for(int i=1;i<=n;i++)
     if(a[i]>0)++cnt;
    return cnt!=1;
}
int main(){
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)
     scanf("%lld",&a[i]),sum+=a[i];
    f[0]=g[0]=-0x7fffffff;//边界
    for(int i=1;i<=n;i++){//往前继承
        f[i]=max(f[i-1]+a[i],a[i]);
        g[i]=max(g[i-1],f[i]);
    }
    f[n+1]=b[n+1]=-0x7fffffff;//Inherited back 
    for ( int I = n-; I; i-- ) { 
        F [I] = max (F [I + . 1 ] + A [I], A [I]); 
        B [I] = max (B [ I + . 1 ], F [I]); 
    } 
    Long  Long ANS = - 0x7FFFFFFF ; // count the first case 
    for ( int I = . 1 ; I <= n-; I ++) ANS = max (ANS, B [I + . 1 ] + G [I]); 
     IF (! Check ()) return COUT << endl << ANS, 0 ; // Laid judgment 
    F [ 0 ] = G [ 0 ] = 0x7FFFFFFF;
    for(int i=1;i<=n;i++){//往前
        f[i]=min(a[i],f[i-1]+a[i]);
        g[i]=min(g[i-1],f[i]);
    }
    b[n+1]=f[n+1]=0x7fffffff;
    for(int i=n;i;i--){//往后
        f[i]=min(f[i+1]+a[i],a[i]);
        b[i]=min(b[i+1],f[i]);
    }
    long long ans2=0x7fffffff;// second answer, then to the smallest sum obtained Save 
    for ( int I = . 1 ; I <= n-; I ++) ANS2 = min (ANS2, B [I + . 1 ] + G [I]); 
     IF ( == ANS2-sUM 0 ) = ANS2 - 0x7FFFFFFF ; // If the resulting sum is intended to undesirable issues 
    the else ANS2 = sUM-ANS2; // otherwise obtained minimum value 
    COUT << max (ANS, ANS2) << endl; / / outputting value 
    return  0 ; 
}

 

Guess you like

Origin www.cnblogs.com/coder-cjh/p/11622676.html