Description
Give you N integers a1, a2 ... aN (|ai| <=1000, 1 <= i <= N).
You should output S.
You should output S.
Input
The input will consist of several test cases. For each test case, one integer N (2 <= N <= 100000) is given in the first line. Second line contains N integers. The input is terminated by a single line with N = 0.
Output
For each test of the input, print a line containing S.
Sample Input
5 -5 9 -5 11 20 0
Sample Output
40
思路:
就是求在1-n的区间,将区间分开两段来求最大字段和。暴力会TLE,所以要优化。
AC代码:
#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> using namespace std; #define INF -0x3f3f3f3f #define T 100010 int a[T],m1[T],m2[T]; int main() { /*freopen("input.txt","r",stdin);*/ int n,i,sum; while(~scanf("%d",&n),n) { int c[T]={0}; m1[0]=m2[n+1]=INF;//初始化顺序和逆序操作的数组,不然进行取最大值时不会出现负数 for(i=1;i<=n;++i){ scanf("%d",&a[i]); if(c[i-1]>=0) c[i]=c[i-1]+a[i]; else c[i]=a[i]; m1[i]=max(c[i],m1[i-1]); }memset(c,0,sizeof(c)); for(i=n;i>=1;--i){ if(c[i+1]>=0) c[i]=c[i+1]+a[i]; else c[i]=a[i]; m2[i]=max(c[i],m2[i+1]); } for(i=1,sum=INF;i<n;++i)//在1-n区间找两个连续的最大子段和 if(m1[i]+m2[i+1]>sum)sum=m1[i]+m2[i+1]; printf("%d\n",sum); } return 0; }
TLE代码:
#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> using namespace std; #define T 100010 int a[T]; int find(int sta,int end) { int k=0,ma=0,mi=-T; for(int i=sta;i<end;++i){ mi=max(mi,a[i]); if(k>=0) { k+=a[i]; ma=max(k,ma); } else { ma=max(k,ma); k=0; } } if(ma<=0)ma=mi; return ma; } int main() { /*freopen("input.txt","r",stdin);*/ int n,i,k,sum; while(~scanf("%d",&n),n) { for(i=0;i<n;++i) scanf("%d",&a[i]); for(i=0,sum=-T;i<n;++i) { k=find(0,i)+find(i,n); sum=max(k,sum); } printf("%d\n",sum); } return 0; }