问题描述:给定整数A1,A2,A3.....An(可能为负数),找出最大邻近子序列之和,如果全为负数,则为零?
算法描述:分治算法是一种利用递归来解决问题的重要技术,由两部分组成:
(1)分割,递归解决更小的问题(当然,基本情形除外)
(2) 攻克,根据子问题的解决方案形成原始问题的解决方案。
针对本问题,可以将整数序列划分为两半,于是最大邻近子序列可能以3中方式出现。
情形1:完全在前半部分
情形2:完全在后半部分
情形3:开始于前半部分,结束于后半部分。
情形1,2就是递归调用,主要分析下情形3的情况,虽然它有n/2个起始点和n/2个截止点,但是考虑到这个序列必须包含前半部分的最后一个数以及后半部分的第一个数,我们可以通过两个连续的循环来计算出这种情形的最大数。
template <Class comparable>
comparable maxSubSum(const vector<comparable> &a,int left,int right)
{
comparable leftmax=0;rightmax=0;leftborder=0;rightborder=0,maxleftborder=0;maxrightborder=0;
int center=(left+right)/2;
if(left==right) return a[left]>0?a[left]:0;
leftmax=maxSubSum(a,left,center);//递归计算完全位于前半部分的最大邻近子序列和
rightmax=maxSubSum(a,center+1,right);//递归计算完全位于后半部分的最大邻近子序列和
for(int i=center;i>=left;i--)//通过两个循环计算开始于前半部分,结束于后半部分的最大邻近子序列和
{
leftborder+=a[i];
if(leftborder>maxleftborder)
maxleftborder=leftborder;
}
for(int i=center;i<right;j++)
{
rightborder+=a[i];
if(rightborder>maxrightborder)
maxrightborder=rightborder;
}
return max3(leftmax,rightmax,maxleftborder+maxrightborder);//选择3个中最大的一个
}
算法描述:分治算法是一种利用递归来解决问题的重要技术,由两部分组成:
(1)分割,递归解决更小的问题(当然,基本情形除外)
(2) 攻克,根据子问题的解决方案形成原始问题的解决方案。
针对本问题,可以将整数序列划分为两半,于是最大邻近子序列可能以3中方式出现。
情形1:完全在前半部分
情形2:完全在后半部分
情形3:开始于前半部分,结束于后半部分。
情形1,2就是递归调用,主要分析下情形3的情况,虽然它有n/2个起始点和n/2个截止点,但是考虑到这个序列必须包含前半部分的最后一个数以及后半部分的第一个数,我们可以通过两个连续的循环来计算出这种情形的最大数。
template <Class comparable>
comparable maxSubSum(const vector<comparable> &a,int left,int right)
{
comparable leftmax=0;rightmax=0;leftborder=0;rightborder=0,maxleftborder=0;maxrightborder=0;
int center=(left+right)/2;
if(left==right) return a[left]>0?a[left]:0;
leftmax=maxSubSum(a,left,center);//递归计算完全位于前半部分的最大邻近子序列和
rightmax=maxSubSum(a,center+1,right);//递归计算完全位于后半部分的最大邻近子序列和
for(int i=center;i>=left;i--)//通过两个循环计算开始于前半部分,结束于后半部分的最大邻近子序列和
{
leftborder+=a[i];
if(leftborder>maxleftborder)
maxleftborder=leftborder;
}
for(int i=center;i<right;j++)
{
rightborder+=a[i];
if(rightborder>maxrightborder)
maxrightborder=rightborder;
}
return max3(leftmax,rightmax,maxleftborder+maxrightborder);//选择3个中最大的一个
}