最大子列和问题
给定K个整数组成的序列{ N1, N2, …, NK },“连续子列”被定义为{ Ni, Ni+1, …, Nj },其中 1≤i≤j≤K。“最大子列和”则被定义为所有连续子列元素的和中最大者。例如给定序列{ -2, 11, -4, 13, -5, -2 },其连续子列{ 11, -4, 13 }有最大的和20。现要求你编写程序,计算给定整数序列的最大子列和。
输入格式:
第1行给出正整数K (≤100000);第2行给出K个整数,其间以空格分隔。
输出格式:
在一行中输出最大子列和。如果序列中所有整数皆为负数,则输出0。
//暴力求解
int MaxSubSeqSum1(int *a,int N){
int Thissum,Maxsum = 0;
for(int i = 0;i<N;i++){
for(int j = i;j<N;j++){
ThisSum = 0;
for(int k = i;k<=j;k++){
ThisSum += a[k]
}
if(ThisSum > MaxSum){
MaxSum = ThisSum;
}
}
}
return MaxSum;
}
int MaxSubSeqSum2(int *a,int N){
int ThisSum,MaxSum = 0;
for(int i = 0;i<N;i++){
ThisSum = 0;
for(int j = i;j<N;j++){
ThisSum += a[j];
if(ThisSum > MaxSum){
MaxSum = ThisSum;
}
}
}
return MaxSum;
}
//在线处理
int MaxSubSeqSum3(int *a,int N){
int ThisSum = 0;
int MaxSum =0;
for(int i = 0;i<N;i++){
ThisSum += a[i];
if(ThisSum > MaxSum){
MaxSum = ThisSum;
}
else if(ThisSum < 0){
ThisSum = 0; //如果前面相加小于零,不能使后面的和增大,舍弃。
}
}
return MaxSum;
}
//分治算法
//返回3个整数中最大值
int Max3( int A, int B, int C ){
return A > B ? A > C ? A : C : B > C ? B : C;
}
int DivideAndConquer(int *a , int left , int right){
int MaxLeftSum , MaxRightSum; //存放左右子问题的解
int MaxLeftBorderSum , MaxRightBorderSum; //存放跨分界线的结果
int LeftBorderSum , RightBorderSum;
int center ;
if(left == right){ //递归结束条件
if(left > 0){
return a[left];
}
else{
return 0;
}
}
center = (left + right)/2;
MaxLeftSum = DivideAndConquer(a,left,center); //递归求左问题的解
MaxRightSum = DivideAndConquer(a,center+1,right); //递归求右问题的解
//求跨越边界的解
MaxLeftBorderSum = 0;
LeftBorderSum = 0;
for(int i = center;i>=left;i--){
LeftBorderSum += a[i];
if(LeftBorderSum > MaxLeftBorderSum){
MaxLeftBorderSum = LeftBorderSum;
}
}
MaxRightBorderSum = 0;
RightBorderSum = 0;
for(int i = center+1;i<=right;i++){
RightBorderSum += a[i];
if(RightBorderSum > MaxRightBorderSum){
MaxRightBorderSum = RightBorderSum;
}
}
return Max3(MaxLeftSum, MaxRightSum, MaxLeftBorderSum + MaxRightBorderSum);
}