循环数组最大子段和
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; }
以上是关于循环数组最大子段和的主要内容,如果未能解决你的问题,请参考以下文章