循環數組最大子段和
阿新 • • 發佈:2019-04-05
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; }
循環數組最大子段和