分治法解决最大连续和

1.步骤:划分子问题–>递归求解子问题–>合并子问题的解

合并的问题:先寻找最佳起点,再寻找最佳终点(从分界点分别向左向右寻找),然后与子问题的最优解比较

关键解决:输出起点和终点的位置 

-1,0   begin=end=2 的情况暂时没有想到办法解决

#include<stdio.h>
#define MAX 100001
int begin=0,end=0;
int maxsum(int *A,int x,int y)
{
	int i,m,v,L,R,max;
	int temp1,temp2;
	if(y-x==1)
		return A[x];	//只有一个元素,直接返回
	m=x+(y-x)/2;	//分治第一步,划分成[x,m),[m,y)
	temp1=maxsum(A,x,m);
	temp2=maxsum(A,m,y);
	if(temp1>temp2)//分治第二部递归求解
		max=temp1; 
	else
		max=temp2;
	v=0;
	L=A[m-1];
	for(i=m-1;i>=x;i--) //左半部分---从分界点往左寻找最大连续和!
	{
		v+=A[i];
		if(L<v||(A[i]==0))
		{
			L=v;
			begin=i;
		}
	}
	v=0;
	R=A[m];
	for(i=m;i<y;i++)
	{
		v+=A[i];
		if(R<v||(A[i]==0))
		{
			R=v;
			end=i;
		}
	}
	if(max>(L+R))
		return max;
	return (L+R);
}
int main()
{
	int A[MAX];
	int max,n,count=1;
	scanf("%d",&n);
	while(n--)
	{
		int i,num;
		begin=end=0;
		scanf("%d",&num);
		for(i=0;i<num;i++)
			scanf("%d",&A[i]);
		max=maxsum(A,0,num);
		printf("Case %d:\n",count++);
		printf("%d %d %d\n",max,begin+1,end+1);
		if(n)
			printf("\n");
	}
	return 0;
}
点赞