题源:实例1.1 最大子列和问题 (20分) ,PTA
分而治之:
#include<stdio.h>
#include<stdlib.h>
int max3(int a, int b, int c);
int divideandconquer(int a[] , int left ,int right);
int maxsubseqsum(int a[], int n);
int main()
{
int n;
scanf("%d",&n);
int *a=(int *)malloc(sizeof(int)*n);
for(int i=0;i<n;i++)
scanf("%d",a+i);
printf("%d",maxsubseqsum(a,n));
return 0;
}
int max3(int a, int b, int c)
{
return a>c?a>b?a:b:c>b?c:b;
}
int divideandconquer(int a[] , int left ,int right)
{
int maxleft,maxright;//存放左右子问题的解
int maxleftbordersum=0,maxrightbordersum=0;//存放跨分界线的结果
int leftbordersum=0,rightbordersum=0;
int center,i;
if(left==right)
{
return a[left]>0?a[left]:0;
}
center=left+(right-left)/2;
maxleft = divideandconquer(a,left,center) ;
maxright = divideandconquer(a,center+1,right);
for(i=center;i>=left;i--)
{
leftbordersum+=a[i];
if(leftbordersum>maxleftbordersum)
maxleftbordersum=leftbordersum;
}
for(i=center+1;i<=right;i++)
{
rightbordersum+=a[i];
if(rightbordersum>maxrightbordersum)
maxrightbordersum=rightbordersum;
}
return max3(maxleft,maxright,maxrightbordersum + maxleftbordersum);
}
int maxsubseqsum(int a[], int n)
{
return divideandconquer(a,0,n-1);
}
为了体会分而治之的思想,自己写了遍代码,感觉写时不是很流畅,有些地方卡壳还有参数写错,导致去找bug……
在线法:
#include<stdio.h>
#include<stdlib.h>
int maxsubseqsum(int a[], int n);
int main()
{
int n;
scanf("%d",&n);
int *a=(int *)malloc(sizeof(int)*n);
for(int i=0;i<n;i++)
scanf("%d",a+i);
printf("%d",maxsubseqsum(a,n));
return 0;
}
int maxsubseqsum(int a[], int n)
{
int ms=0,sum=0;
for(int i=0;i<n;i++)
{
sum+=a[i];
if(sum>ms) ms=sum;
if(sum<0) sum=0;
}
return ms;
}
思路在我看来比分而治之好理解,且代码量极少。
本文介绍了两种解决最大子列和问题的方法:分而治之和在线法。分而治之策略通过递归将问题分解为更小的部分,然后合并解。在线法则使用迭代,逐个检查数组元素并更新最大子序列和。虽然在线法的代码更简洁,但分而治之有助于理解问题的结构。
4146

被折叠的 条评论
为什么被折叠?



