最大子序列和
O(n):DP
O(nlgn):分治法
O(n2):枚举
HDU 1003
Input
The first line of the input contains an integer T(1<=T<=20) which means the number of test cases. Then T lines follow, each line starts with a number N(1<=N<=100000), then N integers followed(all the integers are between -1000 and 1000).
Output
For each test case, you should output two lines. The first line is “Case #:”, # means the number of the test case. The second line contains three integers, the Max Sum in the sequence, the start position of the sub-sequence, the end position of the sub-sequence. If there are more than one result, output the first one. Output a blank line between two cases.
Sample Input
2
5 6 -1 5 4 -7
7 0 6 -1 1 -6 7 -5
Sample Output
Case 1:
14 1 4
Case 2:
7 1 6
AC-O(n)
#include <bits/stdc++.h>
using namespace std;
int main(){
int a[100010],T,N,position,beginum,endnum,maxsum,thissum;
cin >>T;
for(int i=0;i<T;i++){
cin >>N;
for(int j=0;j<N;j++)
cin >>a[j];
position = beginum = endnum =0;
maxsum = thissum = a[0];
for(int k=1;k<N;k++){
if(thissum + a[k] < a[k]){ //如果当前值比a[i]小的话则改为a[i]
thissum = a[k];
position = k; //记录下改的位置
}
else{
thissum = thissum + a[k];
}
if(thissum > maxsum){ //当前值比最大值大,则头尾都要改
maxsum = thissum;
beginum = position;
endnum = k;
}
}
if(i)
cout <<endl;
cout <<"Case "<<i+1<<':'<<endl;
cout <<maxsum<<' '<<beginum+1<<' '<<endnum+1<<endl;
}
return 0;
}
AC-O(nlgn)
//O(nlogn) 分治排序算法
int maxsum_version_1(int *a,int x,int y){ //求区间[x,y)的最大值 [2,3)为a2;
int L,R,v,m,i,max;
if(y-x==1)
return a[x];
m=x+(y-x)/2; //不取m=(y-x)/2 是为了使分界点靠近区间左端点
max=(maxsum_version_1(a,x,m)>maxsum_version_1(a,m,y))?maxsum_version_1(a,x,m):maxsum_version_1(a,m,y);
v=0;
L=a[m-1];
for(i=m-1;i>=x;i--){
v=v+a[i];
L=L>v?L:v;
}
R=a[m];
v=0;
for(i=m;i<y;i++){
v+=a[i];
R=R>v?R:v;
}
return (max>L+R)?max:L+R;