动态规划之钢条 切割
来源:互联网 发布:网络电话软件下载 编辑:程序博客网 时间:2024/05/17 06:23
- 问题描述
假设有长度为n寸的钢管,我们可以切割这段钢管以获得最大的利益(假设切割钢管无花费),价格表pi已知,问如何切割才能是销售收益rn最大。 - 解决方案
对于这个问题我们可以使用递归的方式来解决。
public static int CUT_ROD(int[] p, int n){ if(n == 0){ return 0; } int q = -1; for(int i = 1; i <= n; i++){ q = Math.max(q, p[i] + CUT_ROD(p, n-i)); } return q; }
完成首次切割后,我们将两段钢条看成是两个独立的钢条切割问题,我们通过组合两个相关子问题的最优解来选取组合收益最大者。
虽然递归的方法可以求解该问题,但是仔细分析我们发现递归过程中我们求解的某些子问题是相同的,规模也是一样的。我们可以在求解的过程中将子问题的解保留下来,以便于下次碰到相同的子问题可以直接使用。
public static int MEMOIZED_CUT_ROD(int[] p, int n){ int[] r = new int[n + 1]; for(int i = 0; i < r.length; i++){ r[i] = -1; } return MEMOIZED_CUT_ROD_AUX(p, n, r); } public static int MEMOIZED_CUT_ROD_AUX(int[] p, int n, int[] r){ if(r[n] >= 0) return r[n]; int q = -1; if(n == 0) q = 0; else { for(int i = 1; i <= n; i++){ q = Math.max(q, p[i] + MEMOIZED_CUT_ROD_AUX(p, n-i, r)); } } r[n] = q; return q; }
上面这种方法称作带备忘的自顶向下发,此方法仍自然的递归形式编写过程,但过程会保存每个子问题的解,当需要一个子问题的解时,过程首先检查是否已经保存过此解。
public static int BOTTOM_UP_CUT_ROD(int[] p, int n){ int[] r = new int[n + 1]; r[0] = 0; for(int i = 1; i <= n; i++){ int q = -1; for(int j = 1; j <=i; j++){ q = Math.max(q, p[j] + r[i-j]); } r[i] = q; } return r[n]; }
上面的方法称为自低向上法,该方法一般需要恰当定义子问题“规模”的概念,使得任何子问题的求解都只依赖于“更小的”子问题的求解。
- 总结
动态规划个递归十分相似,动态规划的子问题是可以重复的,递归的子问题一般是规模逐渐减小的。
0 0
- 动态规划之切割钢条
- 动态规划之钢条切割
- 动态规划之钢条切割
- 动态规划之钢条切割
- 动态规划之钢条切割
- 动态规划之钢条切割
- 动态规划之切割钢条
- 动态规划之钢条切割
- 动态规划之钢条 切割
- 动态规划之切割钢条
- 动态规划之钢条切割
- 钢条切割-动态规划
- 切割钢条【动态规划】
- 动态规划-钢条切割
- 动态规划-钢条切割
- 动态规划-钢条切割
- 动态规划 钢条切割
- 钢条切割-动态规划
- 备份:CSDN-markdown编辑器
- python httpConnection详解
- TreeMap的实现原理
- XMLHttpRequest对象
- ubuntu navicat破解
- 动态规划之钢条 切割
- 【LeetCode】107.Binary Tree Level Order Traversal II
- linux下的压缩和备份
- Android之硬盘缓存DiskLrucache完全解析
- 二叉树相关题目
- skipList
- 百度图片url解码
- J2EE系列:Wdatepicker日期控件的使用指南
- Android中调用外部地图程序