动态规划概念讲解

1、基本概念

动态规划和分治方法相似,都是通过组合子问题的解来求解原问题的解。分治方法是将问题分解为相互独立的子

问题,递归地求解这些子问题,然后求原问题的解。与之不同的是,动态规划应用于子问题重叠的情形,即子问题的解依赖于子子问题的求解。在这种情形下,分治方法会做出许多不必要的工作,它会反复地去求解公共子问题。而动态规划对每个子子问题只求解一次,将其解记录在一个表格中,从而无需每次求解一个子子问题时都重新计算,避免了这种不必要的工作。

动态规划通常用来求解最优化问题。这类问题通常具多组解,对于每组解,都有一个值,我们希望求出最优值(

最小值或最大值)的解。我们称这样的解为一个最优解,一个问题可能会存在多个最优解。我们通常按照如下步骤来设计一个动态规划:

1、刻画一个最优解的结构特征;

2、递归地定义最优解得值;

3、计算最优解的值,通常采用自底向上的方法;

4、利用计算出的信息构造一个最优解。

步骤1~3是动态规划求解问题的基础。如果我们仅需要最优解得一个值,则可以忽略步骤4。如果要求解一组最

优解则在步骤3要维护一些额外的信息来,以便构造一个最优解。

2、使用动态规划求解钢条切割问题

问题描述:给定长度为n英寸的钢条和一张价格表pi(i=1,2,...n),求切割钢条的方案,使得收益rn最大。价格表如

下:


例如当n=4时,那么切割方案为共有8种(因为在距离钢条左端i(i=1,2,3....,n-1)英寸处我们可以选择切割或不切

割),分别为:4(收益为9美元)、1+3(收益为9美元)、2+2(收益为10美元)、3+1(收益为9美元)、1+1+2(收益为7美元)、1+2+1(收益为7美元)、2+1+1(收益为7美元)、1+1+1+1(收益为4美元)。因此为了获得最大收益,切割方式为2+2,即把钢条切割成两段2英寸长度。

为了求解规模为n的原问题,我们先求解形式完全一样,但规模更小的子问题。即当完成首次切割后,我们将两

段钢条看成两个独立的钢条切割问题实例。我们通过组合两个相关子问题的最优解,并在所有可能的两种方案切割中选取组合收益最大者,构成原问题的最优解。我们称钢条切割问题满足最优子结构性质:问题的最优解有相关的两个子问题的最优解组合而成,而这些子问题可以独立求解。

除了上述求解方法外,钢条切割问题还存在一种相似的但更为简单的递归求解方法:我们将钢条从左边切割下长

度为i的一段,只对右边剩下的n-i的一段继续进行切割,对左边的一段不再进行切割。即问题的分解的方式为:将长度为n的钢条分解为左边开始的一段,以及剩余部分继续分解的一段。于是可以得到公式:


我们采用自底向上的方法求解,代码如下:

void botom_up(int *p, int n)
{
	int max = 0;
	int i, j;
	int *r = (int *)malloc(sizeof(int)*n);//用来保存子问题的最优解
	r[0] = 0;

	for (i = 1; i <= n;i++)
	{
		max = 0;
		for (j = 1; j <= i;j++)
		{
			if ((p[j] + r[i - j]) > max)
				max = p[j] + r[i - j];
		}
		r[i] = max;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值