最大子段和:
给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值
当所给的整数均为负数时定义子段和为0,依此定义,所求的最优值为: Max{0,a[i]+a[i+1]+…+a[j]},1<=i<=j<=n例如,当(a[1], a[2], a[3], a[4], a[5], a[6])=(-2,11,-4,13,-5,-2)时,最大子段和为20。
输入:输入共2行,第一行为n,为给定数据的数量,第二行共有n个整数,为给定的n个元素
输出:输出一个整数,为给定数据最大子段和。
输入样例:6
-2 11 -4 13 -5 -2
输出样例:
20
算法要求:用分治法解,算法复杂度为O(n* log(n))。
提示:将序列a[1:n]分成长度相等的两段a[1:n/2]和a[n/2+1:n],分别求出这两段的最大字段和,则a[1:n]的最大子段和有三种情形:
(1)a[1:n]的最大子段和与a[1:n/2]的最大子段和相同;
(2)a[1:n]的最大子段和与a[n/2+1:n]的最大子段和相同;
(3) a[1:n]的最大字段和为在a[1:n/2]中包含最后一个元素的最大子段和+ a[n/2+1:n] 中包含第一个元素的最大子段和
#include <iostream>
using namespace std;
int a[100];
int MaxLine(int x,int y){
int mid,i;
int num1,num2,num3;
if(x==y){
if(a[i]<0)
return 0;
return a[i];
}
if(x==y-1){
if(a[x]<0&&a[y]<0)
return 0;
else if(a[x]>=0 && a[y]>=0)
return a[x]+a[y];
else
return a[x]>=a[y]?a[x]:a[y];
}
else{
mid=(x+y)/2;
num1=MaxLine(x,mid);
num2=MaxLine(mid,y);
int sum1=0,leftsum=0;
for(i=mid;i>=x;i--){
sum1+=a[i];
if(sum1>leftsum)
leftsum=sum1;
}
int sum2=0,rightsum=0;
for(i=mid+1;i<=y;i++){
sum2+=a[i];
if(sum2>rightsum)
rightsum=sum2;
}
num3=leftsum+rightsum;
if(num3>=num1 && num3>=num2)
return num3;
if(num1>num2 && num1>num3)
return num1;
if(num2>num1 && num2>num3)
return num2;
}
}
int main(){
int n,i;
cin>>n;
for(i=0;i<n;i++)
cin>>a[i];
cout<<MaxLine(0,n-1);
return 0;
}