最大子段和之分治递归法
Description
给定n(1<=n<=50000)个整数(可能为负数组成的序列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。
Input
第一行输入整数n(1<=n<=50000),表示整数序列中的数据元素个数;
第二行依次输入n个整数,对应顺序表中存放的每个数据元素值。
Output
一行输出两个整数,之间以空格间隔输出:
第一个整数为所求的最大子段和;
第二个整数为用分治递归法求解最大子段和时,递归函数被调用的总次数。
Sample
Input
6
-2 11 -4 13 -5 -2
Output
20 11
代码实现及思想大概.(本人学的也不是很好,也处于一边学习的路上,如有不合适或者理解错误的地方,还请斧正)由于时间问题,思路我将在之后更新出来;
#include<bits/stdc++.h>
using namespace std;
int e=0;
int n,a[50050];
int f(int a[],int l,int r)
{
e++;
int sum=0;
if(l==r)
{
if (a[l]>0)
sum=a[l];
else sum=0;
}
else
{
int m=(l+r)/2;
int suml=f(a,l,m);
int sumr=f(a,m+1,r);
int s1=0;
int sl=0;
for (int i=m;i>=l;i--)
{
sl+=a[i];//这是sL
if (sl>s1) s1=sl;//这个是sL>s1
}
int s2=0;
int sr=0;
for (int i=m+1;i<r;i++)
{
sr+=a[i];
if (sr>s2) s2=sr;
}
sum=s1+s2;
if (suml>sum) sum=suml;
if (sumr>sum) sum=sumr;
}
return sum;
}
int main()
{
int i;
cin>>n;
for (i=0;i<n;i++)
{
cin>>a[i];
}
cout<<f(a,0,n-1)<<" "<<e;
return 0;
}