循环数组最大子段和

Posted fzw1523

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了循环数组最大子段和相关的知识,希望对你有一定的参考价值。

  记得以前好像做过,应该是学长给了个思路才想出来的,明明是一道水题,写了半天全是错的,给自己留个纪念吧,思路很简单:把数组复制一遍接到数组后面,先求最大值

,要是直接求的话肯定错,个数要限制一下,给个例子:4 5 6 7 ,复制之后是 4 5 6 7 4 5  6 7 要是没有个数限制的话就全加上了,之后这个先来一个候选值,因为不一定对

例子是: 1 2 3  -5 3  2 1,自己跑一遍的话可以知道是3 + 2 + 1 + 1 + 2 + 3之前写的会全加上,这个就要另一个思路了,就是反其道而行,找序列中连续最小的然后不要了,感觉很

神奇,这两个候选值选一个最大的就可以了。

代码:

  

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<math.h>
#include<vector>
#include<queue>
using namespace std;
typedef long long ll;
int x[500000];
int main()
{
    int n;
    scanf("%d",&n);
    ll fuck=0;
    for(int i=0;i<n;i++){
        scanf("%d",&x[i]);
        x[n+i]=x[i];
        fuck+=x[i];
    }
    //for(int i=0;i<n*2;i++)  printf("%d
",x[i]);
    ll maxx=0;
    ll sum=0;
    int ge=0;
    for(int i=0;i<n*2;i++){
        if(x[i]+sum>0){
            sum+=x[i];
            maxx=max(maxx,sum);
            ge++;
            if(ge==n){
                sum=0;
                ge=0;
            }
        }
        else{
            sum=0;
            ge=0;
        }
    }
    maxx=max(sum,maxx);
    ll haha=maxx;
    maxx=0;
    ge=0;
    sum=0;
    for(int i=n*2-1;i>=0;i--){
        if(x[i]+sum>0){
            sum+=x[i];
            maxx=max(maxx,sum);
            ge++;
            if(ge==n){
                sum=0;
                ge=0;
            }
        }
        else{
            sum=0;
            ge=0;
        }
    }
    maxx=max(maxx,sum);
    haha=max(maxx,haha);
    ll minn=10000000000;
    sum=0;
    for(int i=0;i<n*2;i++){
        if(x[i]+sum<0){
            sum+=x[i];
            minn=min(minn,sum);
            ge++;
            if(ge==n){
                sum=0;
                ge=0;
            }
        }
        else{
            sum=0;
            ge=0;
        }
    }
    ll lala=minn;
    minn=10000000000;
    sum=0;
    for(int i=n*2-1;i>=0;i--){
        if(x[i]+sum<0){
            sum+=x[i];
            minn=min(minn,sum);
            ge++;
            if(ge==n){
                sum=0;
                ge=0;
            }
        }
        else{
            sum=0;
            ge=0;
        }
    }
    lala=min(minn,lala);
    fuck-=lala;
    haha=max(haha,fuck);
    printf("%lld
",haha);
    return 0;
}

 

以上是关于循环数组最大子段和的主要内容,如果未能解决你的问题,请参考以下文章

51nod 1050 循环数组最大子段和

[51NOD1959]循环数组最大子段和(dp,思路)

1050 循环数组最大子段和

51Nod 1050 循环数组最大子段和 | DP

循环序列_最大子段和变种

51Nod1050 循环数组最大子段和