算法导论 动态规划钢条切割问题 C语言

动态规划钢条切割问题

动态规划(dynamic programming)与分治法类似。分治策略将问题划分为互不相交的子问题,递归求解子问题,再将子问题进行组合,求解原问题。动态规划应用于子问题重叠的情况,在这种情况下,分治法将会对重叠问题进行多次重复求解,而动态规划对每个子问题只求解一次

动态规划方法常用于求解**最优化问题(optimization problem)**。这类问题可能有多个解,每个解有一个值,我们希望寻找具有最优值的解。

设计动态规划算法步骤:

  1. 刻画一个最优解的特征
  2. 递归定义最优解的值
  3. 计算最优解的值
  4. 利用计算出的信息构造一个最优解

例:钢条切割问题
假设钢条价格表

长度i 1 2 3 4 5 6 7 8 9 10
价格p 1 5 8 9 10 17 17 20 24 30

现在对于一根长度为n的钢条,求它能获得的最大效益r

注意到,每一次切割后将得到两根钢铁,下一步,又将这两根钢条看作两个独立的钢铁切割问题。通过组合子问题的最优解,选取组合收益最大者,构成原问题的最优解。钢条切割问题满足最优子结构性质:问题的最优解由相关子问题的最优解组合而成,而这些子问题都可以独立求解
对钢条问题,我们可以再进行简化。对于每次切割后得到的两段钢条,我们只对第二段进行再次切割,对第一段不再切割。

自顶向下递归实现
int CUD_ROD(int *p, int n) {
   
	if (n == 0)return 0;
	int q = INT_MIN;
	for (int i = 1; i <= n;i++) {
   
		if (p[i] + CUD_ROD(p, n - i) > q)q = p[i] + CUD_ROD(p, n - i);
	}
	return q;
}

输出价格数组p以及钢条长度n,返回最大收益r。
当n变大时,程序的运行时间会成倍增长,这是由于程序在递归调用时,对相同参数值进行了反复求解。例如,当n=5时,将会调用CUD_ROD(p, n=0 to 4),求解CUD_ROD(p, n=4)时,又会调用CUD_ROD(p, n=0 to 3)。整个程序中存在大量的重复求解过程。

使用动态规划方法求解最优钢条切割问题

朴素递归算法效率之所以低,是因为他在反复求解子问题。动态规划方法安排求解顺序,对每个子问题只进行一次求解,将其结果保存下来,再次遇到相同子问题时,只需要查询结果,而不需要重新计算。这是典型的时空权衡(time-memory trade-off)

带备忘的自顶向下法

仍按照自然递归的顺序进行编写,但过程中会保存子问题的解于数组r中。过程中首先查询子问题的解是否已经存在,若存在,直接返回解,不存在,则按常规方式进行求解。

int MEMOIZED_CUT_ROD_AUX(int *p, int n, int *r) {
   
	if (r[n] >= 0) return r[n];
	
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值