最大子序列问题_C++

2 篇文章 0 订阅

最大子序列问题

描述:给定整数 A 1 , A 2 , ⋯   , A N A_1, A_2, \cdots, A_N A1,A2,,AN (可能有负数),求 Σ k = i j A k \Sigma_{k=i}^j A_k Σk=ijAk 的最大值(如果所有整数均为负数,则最大子序列和为0)

例:

输入:-2, 11, -4, 13, -5, -2

输出:20

递归分治思想

考虑最大子序列只可能有三种可能,出现在序列的左半部分、右半部分或者跨越左右两半部分。前两种情况可以通过递归的方法实现,递归停止条件为左边界等于右边界,即只有一个数据,第三种情况可以分别计算两边的靠近中边界的最大值再相加来解决。通过比较三个数值的大小,返回最大值。

  • 代码
int MaxSubSum(const int A[], int left, int right) {
	int MaxLeftSum, MaxRightSum;
	int MaxLeftBorder, MaxRightBorder;
	int LeftBorder, RighrBorder;
	int center, i;

	/* 递归停止条件 */
	if (left == right) {
		if (A[left] > 0) {
			return A[left];
		}
		return 0;
	}

	center = (left + right) / 2;
	MaxLeftSum = MaxSubSum(A, left, center);
	MaxRightSum = MaxSubSum(A, center + 1, right);

	MaxLeftBorder = 0;
	LeftBorder = 0;
	for (int i = center; i > left; i--) {
		LeftBorder += A[i];
		if (LeftBorder > MaxLeftBorder) {
			MaxLeftBorder = LeftBorder;
		}
	}

	MaxRightBorder = 0;
	RighrBorder = 0;

	for (int j = center+1; j < right; j++) {
		RighrBorder += A[j];
		if (RighrBorder > MaxRightBorder) {
			MaxRightBorder = RighrBorder;
		}
	}
	return max(max(MaxLeftSum, MaxRightSum), MaxLeftBorder + MaxRightBorder);
	//return 0;
}

动态规划

  • 动态规划

时间复杂度 O(n),只扫描一次即可。

int MaxAdd::solution(const vector<int>& nums)
{
	int ThisSum, MaxSum;
	ThisSum = 0;
	MaxSum = 0;

	vector<int>::const_iterator it;
	for (it = nums.begin(); it < nums.end(); it++) {
		ThisSum += *it;

		if (MaxSum < ThisSum) {
			MaxSum = ThisSum;
		}
		if (ThisSum < 0) {
			ThisSum = 0;
		}
	}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值