1. 程式人生 > >循環數組最大子段和

循環數組最大子段和

i++ spa 最大 iostream 簡單 using 一個 () 最大值

  記得以前好像做過,應該是學長給了個思路才想出來的,明明是一道水題,寫了半天全是錯的,給自己留個紀念吧,思路很簡單:把數組復制一遍接到數組後面,先求最大值

,要是直接求的話肯定錯,個數要限制一下,給個例子: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\n",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\n",haha); return 0; }

循環數組最大子段和