动态规划

动态规划与分治方法相似都是通过组合子问题的解来求解原问题
动态规划通常用来求解最优化问题,这样的问题可以有很多个可行解,每一个解都有一个值,我们希望寻找具有最优值(最大值 或者 最小值)的解,
最优值有一个,但是最优解可能有多个;

通常按如下四个步骤设计一个动态规划算法
1、刻划一个最优解的结构特征
2、递归地定义最优解的值
3、计算最优解的值,通常采用自底向上方法
4、利用计算出的信息构造一个最优解

1、 我这一看就蒙蔽了,我就理解了后面三句;
2、 第二句就是用递归地方法求解,而此处得到的仅仅只是一个结果
3、 第三句就是计算结果,方法有 自底向上 和 自顶向下两种方法
4、 第四句就是得到结果是怎么得出来的,哪些数值组合得到这个结果的

钢条切割

Serling公司购买长钢条,将其切割为短钢条出售。切割工序本身没有成本支出。公司管理层希望知道最佳的切割方案。假定我们知道Serling公司出售一段长为i英寸的钢条的价格为pi(i=1,2,…,单位为美元)。钢条的长度均为整英寸。图15-1给出了一个价格表的样例。

钢条切割问题是这样的:给定一段长度为n英寸的钢条和一个价格表pi(i=1,2,…n),求切割钢条方案,使得销售收益rn最大。注意,如果长度为n英寸的钢条的价格pn足够大,最优解可能就是完全不需要切割。

问题理解(一般这个都跳过,肯定读过了)

长度为n英寸的钢条共有2n-1种不同的切割方案,因为在距离钢条左端i(i=1,2,…n)英寸处,总是可以选择切割或不切割。

如果一个最优解将钢条切割为k段(对某个),那么最优切割方案,将钢条切割为长度分别为i1,i2…ik的小段得到的最大收益为。

对于,。其中,pn对应不切割,对于每个i=1,2,…,n-1,首先将钢条切割为长度为i和n-i的两段,接着求解这两段的最优切割收益ri和rn-i(每种方案的最优收益为两段的最优收益之和)。当完成首次切割后,我们将两段钢条看成两个独立的钢条切割问题实例。通过组合两个相关子问题的最优解,并在所有可能的两段切割方案中选取组合收益最大者,构成原问题的最优解。

钢条切割问题还存在一种相似的但更为简单的递归求解方法:将钢条从左边切割下长度为i的一段,只对右边剩下的长度为n-i的一段继续进行切割,对左边的一段则不再进行切割。这样得到的公式为:。这样原问题的最优解只包含一个相关子问题(右端剩余部分)的解,而不是两个。

java代码

朴素递归算法

package CutRod;public class CutRod1 {private static int p[] = {0,1,5,8,9,10,17,17,20,24,30};public static int CUT_ROD(int p[],int n) {if(n==0) {return 0;}int q=-1;for(int i=1;i<n+1;i++) {q=q>(p[i]+CUT_ROD(p, n-i))?q:(p[i]+CUT_ROD(p, n-i));//不断比较出最大值,最后得出结果,//这里的普通递归方法重复计算了许多相同的内容    如:再求10米的最大值时候  //CUT_ROD(p,4)这个要多次重复计算,如CUT_ROD(p,6)中会有p[2]+CUT_ROD(p,4),CUT_ROD(p,5)会有p[1]+CUT_ROD(p,4),这个本来就是死结果不会变的,我们将CUT_ROD(p,4)保存起来//再次计算他的时候直接取结果就可以了,而不用再次递归重复计算,浪费时间;由此引申出动态规划中//的从顶向下的计算方法,与这里的主要区别就是将各个最大结果保存在了数组之中,从而避免了繁琐的//重复递归调用}return q;}public static void main(String[] args) {int m = CutRod1.CUT_ROD(p, 10);System.out.println(m); }
}

自顶向下

package CutRod;
//加入备忘机制的切割钢条
//自顶向下
public class CutRod {private static int p[] = {0,1,5,8,9,10,17,17,20,24,30};private static int maxP[] = new int[100];static {for(int i =0;i<maxP.length;i++) {maxP[i] = -10;}}public static int cut_Rot(int p[],int n) {if(maxP[n]>0) {return maxP[n];} if(n==0) {return 0;}for(int i=1;i<n+1;i++) {maxP[n] = maxP[n]>(p[i]+cut_Rot(p, n-i))?maxP[n]:(p[i]+cut_Rot(p, n-i));  }return maxP[n];} public static void main(String[] args) {int m = CutRod.cut_Rot(p, 10); for(int i = 1;i<11;i++) {System.out.println(maxP[i]);}}}

自底向上

package CutRod;
//自底向上
public class CutRod2 {private static int maxP[] = new int[11];private static int p[] = {0,1,5,8,9,10,17,17,20,24,30};static {for(int i =0;i<maxP.length;i++) {maxP[i] = 0;}}public static int CUT_ROD(int p[],int n){for(int j=1;j<n+1;j++) {for(int i = 1;i<j+1;i++) {maxP[j] = maxP[j]>(p[i]+maxP[j-i])?maxP[j]:(p[i]+maxP[j-i]);}}return maxP[n];}public static void main(String[] args) {int m = CutRod2.CUT_ROD(p, 10);for(int i = 0;i<maxP.length;i++) {System.out.println(maxP[i]);}}
}

重构建(可以得出切割方法)

package CutRod;public class CutRod3 {private static int p[] = {0,1,5,8,9,10,17,17,20,24,30};private static int maxp[] = new int[11];private static int edge[] = new int[11];static {for(int i = 0;i<maxp.length;i++) {maxp[i] = 0;}}public static int CUT_ROD(int p[],int n) {for(int j=1;j<n+1;j++) {for(int i =1;i<j+1;i++) {if(maxp[j]<p[i]+maxp[j-i]) {maxp[j] = p[i]+maxp[j-i];edge[j] = i; } }}      return 0;}public static void main(String[] args) {int n = 9;CutRod3.CUT_ROD(p, n);while(n>0) {System.out.println(edge[n]);n = n - edge[n];}}
}

钢条切割(动态规划问题)相关推荐

  1. 算法设计与分析——动态规划(二):钢条切割

    分类目录:<算法设计与分析>总目录 相关文章: · 动态规划(一):基础知识 · 动态规划(二):钢条切割 · 动态规划(三):矩阵链乘法 · 动态规划(四):动态规划详解 · 动态规划( ...

  2. 《算法导论》中动态规划求解钢条切割问题

    动态规划算法概述 动态规划(dynamic programming)1是一种与分治方法很像的方法,都是通过组合子问题的解来求解原问题.不同之处在于,动态规划用于子问题重叠的情况,比如我们学过的斐波那契 ...

  3. 钢条分割 动态规划java_【动态规划】初识,钢条切割问题

    正文之前其实动态规划老早之前就看过, 但是可惜的是印象不深,到今天彻底忘得差不多了,这两天看<算法导论>终于让我啃下了二叉搜索树和红黑树两个家伙,虽然还未曾熟练于胸,但是基本能用了...现 ...

  4. 动态规划,java实现算法导论15章钢条切割

    来自浙江理工大学在读研究生Yuner: github地址 个人博客地址 此问题dp式 :rn = max(pi + r(n-1)) 不使用dp,用普通的递归方式来求解 //使用普通的方法来计算钢条切割 ...

  5. 动态规划经典例题:钢条切割

    一.递归算法 如果在第i个地方切割,就把钢条分为两个长度为i,n-i的钢条,问题转化为求这切割两个钢条的最大价值之和 考虑到不切割时的价值 只要比较不切割时的价值和所有切割情况价值和的最大值即可 递归 ...

  6. 《算法导论》学习(十七)----动态规划之钢条切割(C语言)

    文章目录 前言 一.钢条切割问题 1.问题背景 2.问题描述 3.问题的难点 (1)情况较多 (2)消除重复子问题 二.问题解决方案 1.问题的特点 (1)最优化子结构 (2)重复子问题 2.最优化解 ...

  7. 动态规划 — 钢条切割问题

    动态规划: 什么是动态规划? 动态规划算法的基本思想与分治法类似,也是将待求解的问题分解为若干个子问题(阶段),按顺序求解子阶段,前一子问题的解,为后一子问题的求解提供了有用的信息.在求解任一子问题时 ...

  8. 动态规划:钢条切割问题

    一.题目 钢条切割问题 是<算法导论>一书中介绍动态规划时的一道引题.即: 某公司购买长钢条,将其切割为短钢条出售.假设切割工序没有成本支出,已知长度为 i 的钢条出售价格为 pi ,钢条 ...

  9. 钢条切割问题(动态规划)

    钢条切割问题-动态规划 问题描述 问题分析 定义 递推公式: 算法实例 伪代码 代码实现 问题描述 某公司购买长钢条,将其切割为段钢条出售.切割工序本身没有成本支出.公司管理层希望知道最佳的切割方案. ...

最新文章

  1. 微信跳转手机默认浏览器打开的实现方式
  2. mysql常用sql语句优化
  3. 多面体 (Multipatch)
  4. 笔记,Vector类模板的基本功能
  5. ssas从mysql获取数据库_通过AMO获取SQL Server SSAS信息
  6. 如何监测mysql主从复制状态_如何实时检测mysql主从状态,并做邮件告警?
  7. SAP License:写给想入行或是想转行的朋友们
  8. Android 获取sim卡序列号
  9. 《马克思主义哲学原理》考点知识串讲-自考
  10. Vue:embed结合ElementUI中dialog实现PDF文件预览
  11. 机器学习之Python分析圆周率
  12. 抓取青果教务系统信息
  13. 修复计算机会没有桌面文件吗,电脑桌面文件不见了怎么恢复
  14. Python爬虫简介
  15. 新C++(9):谈谈,翻转那些事儿
  16. BUCT数据结构——图(拓扑排序、关键路径)
  17. 1.产品/数据产品设计
  18. 关于网站504问题排查
  19. java案例----用户注册--发送邮件并激活/发送邮件验证码
  20. ubuntu 安装 nvidia 显卡驱动

热门文章

  1. 单板计算机硬件系统有什么,单板硬件是什么意思
  2. 用投票机制寻找影响力节点:VoteRank plus Method
  3. matlab gcv,广义交叉验证
  4. [数据结构] python 队列解决迷宫问题
  5. Docker安装Kafka教程(超详细)
  6. javax maven项目缺少_Eclipse项目中的Maven:软件包javax.ws.rs不存在
  7. 微信扫描二维码登陆的实现原理
  8. 腾讯云运维TCA题库(实时更新)
  9. python中的io模块_Python的StringIO模块和cStringIO模块
  10. 在汉化新世纪论坛针对恶意插件的发言