您的位置:首页 > 其它

杭电1003——Max Sum(最大连续子序列和、递归分治)

2016-02-18 15:52 225 查看
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1003

本题使用递归分治求解最大子序列问题。

# include<stdio.h>
# include<malloc.h>

typedef struct{
int left;//区间的左下标
int right;//区间的右下标
int maxsum;//区间最大和
}Sum;

Sum maxSum(int *A,int x,int y);

int main()
{
int t,n,i,j;
int *num;
scanf("%d",&t);
for(j=1;j<=t;j++)
{
scanf("%d",&n);
num=(int *)malloc(sizeof(int)*(n+1));
for(i=0;i<n;i++)
{
scanf("%d",num+i);
}
Sum tsum=maxSum(num,0,n-1);
printf("Case %d:\n%d %d %d\n",j,tsum.maxsum,tsum.left+1,tsum.right+1);
if(j<t)
printf("\n");
free(num);
num=NULL;
}
return 0;
}

Sum maxSum(int *A,int x,int y)
{
int mid=(x+y)/2,i,L,R,v=0,tl=x,tr=x;
Sum tsum,lsum,rsum;
if(x==y)
{
tsum.maxsum=*(A+x);
tsum.left=tsum.right=x;
return tsum;
}
lsum=maxSum(A,x,mid);
rsum=maxSum(A,mid+1,y);
tsum=lsum.maxsum>rsum.maxsum?lsum:rsum;
//L和R不能取0,因为数的范围是-1000~-1001,有可能实际maxsum为负数
//L和R仍然为初始值0(L>=v和R>=v,L和R均未修改),以至于后面会将这个
//误以为正确的(L+R=0)>真正的maxsum,故而会导致错误。
L=-1001;
for(i=mid;i>=x;i--)
{
v=v+*(A+i);
if(L<=v)
{
L=v;
tl=i;
}
}
v=0;
R=-1001;
for(i=mid+1;i<=y;i++)
{
v=v+*(A+i);
if(R<v)
{
R=v;
tr=i;
}
}
if(L+R>tsum.maxsum)
{
tsum.maxsum=L+R;
tsum.left=tl;
tsum.right=tr;
}
//几个不同的解,取第一个解
else if(L+R==tsum.maxsum&&(tl<tsum.left||(tl==tsum.left&&tr<tsum.right)))
{
tsum.left=tl;
tsum.right=tr;
}
return tsum;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: