求解最大连续子序列和问题

求解最大连续子序列和问题

【问题描述】给定一个有n(n>=1)个整数的序列,求出其中最大连续子序列的和。例如序列(-2,,11,-4,13,-5,-2)的最大子序列和为20,序列(-6,2,4,-7,5,3,2,-1,6,-9,10,-2)的最大子序列和为16。规定一个序列的最大连续子序列和至少是0,如果小于0,其结果为0。

【问题求解】
          最大连续子序列只可能出现在3个地方:
          第一种:该子序列完全落在左半部分,即a[0...mid]中,采用递归求出其最大连续子序列和maxLeftSum
          第二种:该子序列完全落在右半部分,即a[mid+1...right]中,采用递归求出其最大连续子序列和maxRightSum
          第三种:该子序列跨越序列a的中部而占据左、右两部分。

源程序如下

#include <iostream>
#include <algorithm>
using namespace std;


//求解最大连续子序列和问题
long maxSubSum(int a[],int left,int right) {
	int i, j;
	long maxLeftSum, maxRightSum;
	long maxLeftBorderSum, leftBorderSum;
	long maxRightBorderSum, rightBorderSum;
	if (left==right) {                         //当子序列只有一个元素时,递归出口
		if (a[left]>0) {
			return a[left];                  //该元素大于0时返回它
		}
		else {
			return 0;                           //该元素小于或者等于0时,返回0
		}
	}

	int mid = (left + right) / 2;              //求中间位置
	maxLeftSum= maxSubSum(a,left,mid);       //求左边的最大连续子序列之和
	maxRightSum=maxSubSum(a, mid +1,right);      //求右边的最大连续子序列之和

	maxLeftBorderSum = 0;   leftBorderSum = 0;
	for (i = mid; i >= left;i--) {        //求出以左边加上a[mid]元素构成的序列的最大和
		leftBorderSum += a[i];
		if (leftBorderSum> maxLeftBorderSum) {
			maxLeftBorderSum = leftBorderSum;
		}
	}

	maxRightBorderSum = 0;  rightBorderSum=0;
	for (j = mid+1; j <= right; j++) {        //求出以左边加上a[mid]元素构成的序列的最大和
		rightBorderSum += a[j];
		if (rightBorderSum > maxRightBorderSum) {
			maxRightBorderSum = rightBorderSum;
		}
	}

	//返回三者之中的最大值
	return max(max(maxLeftSum, maxRightSum), maxLeftBorderSum+ maxRightBorderSum);

}


int main() {
	int n = 0;
	cout << "请输入数组元素的个数" << endl;
	cin >> n;
	int *a = new int[n];
	cout << "请输入数组的元素" << endl;
	for (int i = 0; i < n;i++) {
		cin >> a[i];
	}
	cout << "最大连续子序列的和为:" << maxSubSum(a, 0, n - 1) << endl;
	system("pause");
	return 0;
}

输出结果:

请输入数组元素的个数
6
请输入数组的元素
-2 11 -4 13 -5 -2
最大连续子序列的和为:20
请按任意键继续. . .

【算法分析】设求解序列a[0..n-1]最大连续子序列和的执行时间为T(n),第(1)(2)种情况的执行时间为T(n/2),第(3)中情况的执行时间为O(n),所以得到以下递推式:

      T(n)=1;                                 当n=1时

      T(n)=2T(n/2)+n                     当n>1时

容易推出T(n)=O(nlog2n)

  • 2
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值