1. 程式人生 > >1049 最大子段和

1049 最大子段和

return 51nod name 長度 black 最長 quest sin http

1049 最大子段和 基準時間限制:1 秒 空間限制:131072 KB 分值: 0 難度:基礎題 N個整數組成的序列a[1],a[2],a[3],…,a[n],求該序列如a[i]+a[i+1]+…+a[j]的連續子段和的最大值。當所給的整數均為負數時和為0。 例如:-2,11,-4,13,-5,-2,和最大的子段為:11,-4,13。和為20。 Input
第1行:整數序列的長度N(2 <= N <= 50000)
第2 - N + 1行:N個整數(-10^9 <= A[i] <= 10^9)
Output
輸出最大子段和。
Input示例
6
-2
11
-4
13
-5
-2
Output示例
20

思路是動態規劃,時間復雜度 O(N)
  • 對於前i個數來說,若前i-1個數的最長子段和為負,則前i個數的最長子段和為第i個數本身。(因為前面最大子段和為負,所以加上後反而更小)
  • 對於前i個數來說,若前i-1個數的最長子段和為正,則加上自己
  • 邊界dp[0]=0,每一次更新最大值
  • 小心點,用long long,不然會溢出
技術分享圖片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 long long ans[100000],s[100000];
 5 
 6 inline int read()
 7 {
 8     char ch=getchar();
9 int k=0,a=1; 10 while (ch<0 || ch>9) { 11 if (ch==-) a=-1; 12 ch=getchar(); 13 } 14 while (ch>=0&&ch<=9) k=k*10+(ch^48),ch=getchar(); 15 return a*k; 16 } 17 18 int main() 19 { 20 long long n,m=1,k=0; 21 m<<=63; 22 scanf ("
%lld",&n); 23 for (int i=1;i<=n;i++) 24 { 25 scanf ("%lld",&s[i]); 26 if (s[i]>=0) k=1; 27 } 28 if (k==0) 29 { 30 printf("0"); 31 return 0; 32 } 33 for (int i=1;i<=n;i++) 34 { 35 if (ans[i-1]<=0) ans[i]=s[i]; 36 else ans[i]=ans[i-1]+s[i]; 37 m=max(ans[i],m); 38 } 39 printf("%lld",m); 40 return 0; 41 }
View Code

1049 最大子段和