最大子段和
给定由n个整数(可能有负整数)组成的序列(a1,a2,…,an),最大子段和问题要求该序列形如 的最大值(1<=i<=j<=n),当序列中所有整数均为负整数时,其最大子段和为0。
用分治法求解。
源代码:
#include <iostream>
using namespace std;
int MaxSubSum(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 = MaxSubSum(a, left, center);
int rightsum = MaxSubSum(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 i=center+1; i<=right; i++)
{ rights += a[i]; if (rights >s2) s2= rights; }
sum = s1+s2;
if (sum < leftsum) sum = leftsum;
if (sum < rightsum) sum = rightsum;
}
return sum; }
int main()
{
int n,i,sum;
int *a;
cout<<"请输入n值:";
cin>>n;
a=(int *)malloc(sizeof(int)*(n+1));
cout<<"请输入"<<n<<"个整数:";
for(i=1;i<=n;i++)
cin>>a[i];
sum=MaxSum(n,a);
cout<<"最大子段和为:"<<sum<<endl;
return 0;
}
用动态规划法求解。
源代码:
#include <iostream>
using namespace std;
int MaxSum(int n, int *a)
{ int sum=0,b=0,i=0,besti=0,bestj=0;
for (int j=1; j<=n; j++)
{ if (b>0) b+= a[j];
else {b=a[j];i=j;}
if (b > sum) {sum=b; besti=i; bestj=j;}
}
return sum;
}
int main()
{
int n,i,sum;
int *a;
cout<<"请输入n值:";
cin>>n;
a=(int *)malloc(sizeof(int)*(n+1));
cout<<"请输入"<<n<<"个整数:";
for(i=1;i<=n;i++)
cin>>a[i];
sum=MaxSum(n,a);
cout<<"最大子段和为:"<<sum<<endl;
return 0;
}
截图: