【动态规划】连续子数组的最大和,动态规划思想和填表法实现。

最近接触到了一些动态规划的题目,也翻阅了好多资料,研究了一下动态规划的思想,现在来个总结。

https://www.nowcoder.com/practice/459bd355da1549fa8a49e350bf3df484?tpId=13&tqId=11183&tPage=2&rp=2&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

例如:{1,-5,6,7,-3,5,2},连续子向量的最大和为17(从第2个开始,到第6个为止)。给一个数组,返回它的最大连续子序列的和。

动态规划是一种思想,在变化的事物中找出不变的规律。关于动态规划的数学证明和高深一点的数学理论这里不谈了,这里讲一下笔者弄懂了的填表法实现动态规划。

我们需要一张表,去按照题目的要求丰满这张表,说白了就是在这个表当中列举出所有可能的情况,然后在数据当中找出不变的规律,然后用代码描述出来,就能够解决题目所求。

我们分析这个问题,要求最大连续子序列的和,有几个关键的点连续、最大,这是对我们解题实现手段的限制,同时也是我们应该利用到的特性,前面说过,填表法就是找出所有可能的情况,现在我们看表

通过表格我们可以发现,17就是我们要找的答案,在填表的过程没有直接发现数字之间的规律。比如,下一个答案和上面的数字有一定的数学关系。填完表之后从17在表中的位置发现了如上规律,接下来我们要做的就是用代码来实现这个规律。

也可以通过数学推导发现规律:

发现:规律是下一次的结果仅仅取决于上一次的状态和本次的状态,表中所填的数据每一行保证了往前的子段都是连续的,我们能够得到当前的连续子段最大和是:上次最大子段和加上本次新的元素和与本次单个元素两个的最大值。整体的和就是每次寻找得到的所有最大值里面的最大值。(动态规划一般是上一次状态和本次状态的关系,从而可以遍历到所有的情况)

int FindMax(int num[], int size)
 {
 
	if (size <= 0)
	{
		return 0;
	}
	int max = num[0];
	int tmp = num[0];
	for (int i = 1; i < size; i++)
	{
		tmp = tmp + num[i];
		if (num[i] > tmp)
			tmp = num[i];
		if (tmp > max)
			max = tmp;
	}
	return max;
}

 EOF

发布了157 篇原创文章 · 获赞 98 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_43447989/article/details/101276484