算法第三章上机实践报告

算法第三章上机实践报告

组员:高珞洋,何汶珊

实践题目

7-2 最大子段和
给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整数均为负数时,定义子段和为0。
要求算法的时间复杂度为O(n)。

问题描述

由于要求时间复杂度是O(n),因此递归的方法被砍,只能另外谋求生计
当时间复杂度为O(n),第一反应是用一个for循环,但是如何能只用一个for循环得出结果呢?
自然想到在循环遍历的时候将当前最优解存起来,最后进行一个比较,选择最好的那个解
于是就用到动态规划法来解决问题。

算法描述

算法的核心在于递归方程

MaxSum[i] = ele[i]    i=0
MaxSUm[i] = max{ele[i], ele[i] + MaxSum[i - 1]}     0 < i < n

因此着重讲解递归方程的求得过程
首先对原输出和辅助记录空间进行定义

ele[i]:序列的第i - 1个元素,i从0开始(数组下标)
MaxSum[i]:从ele[0],以ele[i]为尾数的最大子段和(可能不包括ele[0],ele[1]....ele[i - 1])

然后我们分析最开始的情况,从第一个数开始
第一个数有两种情况,小于等于或0大于0。若小于等于0,则最大子段和必不包括它,因为它是第一个数。如果是大于0,则最大子段和有可能包括它。
然后到第二个数,先不管第二个数的正负,根据上一条,如果第一个数ele[0]大于0,那么序列{ele[0],ele[1]}对应的MaxSum[1]=ele[0]+ele[1];如果ele[0]小于0,对应的MaxSum[1]=ele[1],及最大子段和为本身,因为前面只有一个数还小于0,所以必不要它
再看第三个数,在这时候我们将前面的所有数,不管有多少个(现在是两个),都抽象成“前面的数”,它的值为MaxSum[i-1]。那么我们的第三个数就会变成“前面的数”的后面那个数,也就变成了“第二个数”。那么根据上面第二个数的判断,如果“前面的数”小于0,那么“前面的数”都不要了,其最大子段和为本身;反之,最大子段和为“前面的数”加上本身。
也就是说,当前我们看第i个数ele[i],这个数之前的最大子段和为MaxSum[i - 1],如果MaxSum[i - 1] < 0,那么以ele[i]为尾数的最大子段和MaxSum[i]必为ele[i],否则,其为
为统一,我们将第一个数的最大子段和定义为其本身,即:

MaxSum[0] = ele[0]  

注意,这里有个坑,就是以ele[i]结尾的序列,他的最大子段和不一定包括ele[i]。很多在上面的推导过程中都发现了,序列{ele[0],ele[1]}的最大序列可以是ele[0](ele[0]>0, ele[1] < 0)。 而我们MaxSum存的是以ele[i]为尾数的最大子段和,因此MaxSum的最后一个数MaxSum[n]并非最终答案。序列{ele[0],ele[1]...ele[n]}的最大子段和可能为{ele[i],ele[i+1]...ele[j]}(0<i<j<n),那么最终答案应该是MaxSum[j]。
因此我们需要额外一个变量来存放MaxSum中的最大值(当然你也可以得到MaxSum后遍历找最大)。

算法时间及空间复杂度

时间复杂度

无非就是循环判断,T(n) = O(n)

空间复杂度

需要一个和原序列等大的辅助空间来记录,S(n) = O(n)

心得体会

动态规划实际上没有很复杂,代码量也非常少。辅助空间的存在省去了很多额外的计算步骤,这是它在计算量和时间程度优于递归的原因之一。
和分治法不同的是,动态规划的子问题不是相互独立的。比如在这道题中,去掉每个序列的最后一个数所得到的新的序列就是一个新的子问题,可以看出他们存在包含的关系。
动态规划法的难点在于求解递归方程,说实话递归方程出来后,代码的编写一气呵成。大部分时间还是花在了分析问题、求解递归方程上。
所以递归方程是利用动态规划法解题的核心。

核心源码

for (int i = 0; i < n; i++) {
		if (i == 0) {
			maxSum[i] = elements[i];
		}
		else
		{
			maxSum[i] = max(elements[i], (elements[i] + maxSum[i - 1]));
		}
		if (maxSum[i] > maxResult) {
			maxResult = maxSum[i];    //maxResult为额外存放MaxSum中最大值的变量
		}
	}
posted @ 2019-10-17 14:14  BlackDn  阅读(227)  评论(0编辑  收藏  举报
https://blog-static.cnblogs.com/files/luoyang0515/live2d.js https://files.cnblogs.com/files/kousak/waifu.css
Live2D