您的位置:首页 > 其它

求数组的子数组之和的最大值(动态规划)

2014-09-20 20:46 169 查看
大三上学期虽然上过《算法设计与分析》,杨红云老师讲的也很好,可是自己在工作室做项目又在学生会担任干部,时间很紧,课后自己又不去复习,反而利用上机课休息,浪费了大好时光。出来混,迟早要还的,于是现在又重新一个个理解递归、动态规划等经典算法,不过还好课也是听过了,只是课后没有去巩固,所以有些思想还是记得的,有助于现在的理解,好让自己融会贯通,打通任督二脉。

动态规划的特点:最有子结构,无后效性,重叠子问题。

动态规划和分治法类似,其基本思想也是讲带求解问题分解成若干个子问题,先求出子问题,然后从这些子问题得出原问题的解,这就是自底向上的解法。与分治法不同的是,适用于动态规划的问题,经分解往往不是相互独立的,若用分治法求解得到的子问题太多,可能要耗费指数时间。动态规划可以用备忘录记录子问题的解。

动态规划的设计步骤:

1.找出最优解性质,刻画其结构特征;

2.递归定义最优值;

3.以自底向上的方式求得最优值;

4.根据计算最优值时得到的信息,构造最优解。

其中,若只要求算出最优值,1-3步即可,如果需要求得最优解,则计算时要记录更多的信息,以便构造最优解。

动态规划在我理解中,自底向上这个词很关键,好比我从到峡谷对面去,那么要在峡谷之间的铁索上面放一块一块的木板,设从这边的山谷A到对面的山谷B,如果我想过去的话,我放一块木板再踏上木板,然后再放一块木板我再踏上这块木板,一直这样放木板到对面,踏到了对面B。动态规划则是逆过程,如果要到达B,则是需要B前山谷有块木板,它前面又要有一块。。。然后回到起始点A。动态规划也有点像这个过程,有点过河可以柴桥的感觉,它可以不管已经踏过的木板。

在《编程之美》186面有这个解法:

考虑第一个元素a[0],以及最大的一段数组(a[i]......a[j]),分以下三种情况:

1.当0=i=j,a[0]为最大;

2.当0=i<j,和最大一段从a[0]开始;

3.当0<i,元素a[0]和最大的一段木有关系。

书上的代码比较好,容易看出动态规划的思想,是从后面一直往前推,一直推到a【0】,不过我贴出自己用动态规划写的代码:

#include<stdio.h>
int MaxSum(int* a,int size){
	int sum = a[0],max = 0;
	for(int i=1; i<size; i++){
		if(sum < 0) sum = 0;
		sum += a[i];
		if(sum > max) max = sum;
	}
	return max;
}
int main(){
	int a[] = {	1,-2,3,5,-3,2};
	int max = MaxSum(a,6);
	printf("%d\n",max);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: