算法设计与分析第二章作业

最大字段和的分治算法

,对一个数组求其最大子段和,可采用分治思想将其一分为二,例如给定所求为a[n],就可将所给序列分成a[0:n/2] 和 a[n/2 + 1:n]两个部分,则最大值有一下三种情况:

①整个序列的子段和在左半部分
②整个序列的子段和在右半部分
③整个序列的子段和在两个部分的中间连接部分

通过对maxsum函数进行递归可求出前两种情况下的最大子段和,而针对第三种情况,则需要特殊处理,从mid所指位置分两部分向两边搜索,将两部分找到收到的最大和相加,最后对三种情况下算出字段和进行对比,选出其中最大值即为所求最大子段和。

一、关键算法伪代码描述 

int maxsum(int *a,int left,int right)
{
	if(left==right)  return a[left];//当长度为1时直接返回

	mid=(left+right)/2;//二分求中间值
	lsum=maxsum(a,left,mid);//对左半部分递归求子段和
	rsum=maxsum(a,mid+1,right);//对右半部分递归求子段和
	for(int i=mid;i>=left;i--)
	{
		temp+=a[i];
		if(temp>=s1) s1=temp;//比当前子段和大就赋值
	}
	temp=0;
	for(int i=mid+1;i<=right;i++)
	{
		temp+=a[i];
		if(temp>=s2) s2=temp;
	}//两部分操作相同
	msum=s1+s2;//合并两部分和
	return max(max(lsum,rsum),msum);//比较三者大小
} 

注:max函数为求两者中较大值。

二、整体代码展示

#include<iostream>
using namespace std;

int max(int x,int y)
{
	return x>y?x:y;
}

int maxsum(int *a,int left,int right)
{
	if(left==right)  return a[left];
	int mid=(left+right)/2;
	int lsum=maxsum(a,left,mid);
	int rsum=maxsum(a,mid+1,right);
	int s1(0),s2(0),temp(0),msum;
	for(int i=mid;i>=left;i--)
	{
		temp+=a[i];
		if(temp>=s1) s1=temp;
	}
	temp=0;
	for(int i=mid+1;i<=right;i++)
	{
		temp+=a[i];
		if(temp>=s2) s2=temp;
	}
	msum=s1+s2;
	return max(max(lsum,rsum),msum);
	
} 

int main()
{
	int n;
	cin>>n;
	int *a = new int[n];
	for(int i=0;i<n;i++)
	{
		cin>>a[i]; 
	} 
	cout<<maxsum(a,0,n-1);
	return 0;
}

三、算法时间复杂度

分解子问题时间复杂度为O(1)

求解子问题时间复杂度为2T(n/2)

合并子问题算法时间复杂度为O(n)

由主定理得:

T(n)=2T(n/2)+O(n)  ~~~>  O(nlogn)

主定理:

 四、体会与思考

1.递归与分治法

分治法的思想就是将大问题分成小份,一份一份解决最后合并解得出答案,其与递归方法紧密相连,在用递归进行分治法解决问题时,要注意问题规模最小时的情况,可用与做退出判断,递归过程中要清楚具体操作的是哪部分数据,捋清递归顺序。

2.如何正确分治

在例子大整数乘法中,通过式子形式转换,减少了一个要求的子问题,对算法时间复杂度有所提升,所以在划分子问题时尽可能找到最合理的划分方法,而且一定要确定所研究的问题再分成若干解后对算法复杂度有所提升,且小解合并与原解相同,才考虑使用分治法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值