分治法
求解时分治,[1, n]的最大子段和只可能出现在[1, n / 2]或者[n / 2 +1, n]或者起点位于[1, n / 2],后者位于[n / 2 + 1, n]。
就可以直接分治最大子段和。时间复杂度O(nlog(n))。
#include<iostream>
using namespace std;
int MaxSum(int a[],int left,int right)
{
int sum=0;
if(left==right)
sum=a[left]>0?a[left]:0;
else
{
int center=(left+right)/2;
int leftsum=MaxSum(a,left,center);
int rightsum=MaxSum(a,center+1,right);
int s1=0;
int lefts=0;
for(int i=center;i>=left;i--)
{
lefts+=a[i];
if(lefts>s1)
s1=lefts;
}
int s2=0;
int rights=0;
for(int j=center+1;j<=right;j++)
{
rights+=a[j];
if(rights>s2)
s2=rights;
}
sum=s1+s2;
if(sum<leftsum)
sum=leftsum;
if(sum<rightsum)
sum=rightsum;
}
return sum;
}
int main()
{
int i,n,a[200];
cin>>n;
for(i = 0;i < n;i++)
cin>>a[i];
cout<<MaxSum(a,0,n-1)<<endl;
return 0;
}
动态规划法
(文字来源:动态规划解最大子段和问题)
#include<iostream>
using namespace std;
int MaxSum(int a[],int n)
{
int sum=0,b=0;
for(int i=0;i<n;i++)
{
if(b>0)
b+=a[i];
else
b=a[i];
if(b>sum)
sum=b;
}
return sum;
}
int main()
{
int i,n,a[200];
cin>>n;
for(i = 0;i < n;i++)
cin>>a[i];
cout<<MaxSum(a,n)<<endl;
return 0;
}