最大子段和问题。给定由n个整数组成的序列,求序列中子段的最大和,若所有整数均为负整数时定义最大子段和为0。
例如, 当(a1,a2,a3,a4 ,a5,a6) = (-2,11,-4,13,-5,-2)时,最大子段和为: a2+a3+a4=20
输入格式:
第一行输入整数个数n(1≤n≤10000),再依次输入n个整数。
输出格式:
输出第一行为最大子段和,第二行为子段第一个数和最后一个数在整个序列中的位序。
输入样例1:
6
-2 11 -4 13 -5 -2
输出样例1:
20
2 4
#include <iostream>
#include<cmath>
#include <ctime>
using namespace std;
int main()
{
int n,j1=0,j2=0;
cin>>n;
int *a=new int[n+1];
int t=0,max=0;
for(int k=1;k<=n;k++)
cin>>a[k];
for(int i=1;i<=n;i++){
if(t+a[i]>=a[i])
{
t=t+a[i];
}
else
{
t=a[i];
j1=i;
j2=i;
}
if(max<=t)
{
max=t;
j2=i;
}
}
if(max<0)
cout<<0<<endl;
else
cout<<max<<endl;
cout<<j1<<" "<<j2<<endl;
return 0;
}
分治法
int maxsub(int a[],int l,int r)
{
int c,i,sum,l_sum,r_sum,l_max,r_max;
c=(l+r)/2;
if(l==r)
return a[l]>0?a[l]:0;
else
{
l_sum=maxsub(a,l,c);
r_sum=maxsub(a,c+1,r);
sum=0;
l_max=0;
for(i=c;i>=l;i--)
{
sum+=a[i];
if(sum>l_max)
l_max=sum;
}
sum=0;
r_max=0;
for(i=c+1;i<=r;i++)
{
sum+=a[i];
if(sum>r_max)
r_max=sum;
}
sum=r_max+l_max;
if(sum<l_sum)
sum=l_sum;
if(sum<r_sum)
sum=r_sum;
}
return sum;
}