给定一段长度为n英寸的钢条和一个价格表p,求切割钢条方案(钢条的长度均为整英寸),使得销售收益最大。

我们可以计算出长度为n英寸的钢条共有2的(n-1)次方种不同的切割方案。
为解决规模为n的原问题,我们可以这样考虑。先求解形式完全一样,但规模更小的子问题。我们将钢条左边切割下长度为i的一段(i的取值范围是[1, n]),然后只对右边剩下的长度为n-i的一段继续进行切割(递归求解)。即问题的分解方式为:将长度为n的钢条分解为左边开始一段,以及剩余部分继续分解的结果。这样我们就可以做出如下解答:

function cut_rod(p, n) {if (n == 0) return 0;let sum = -Infinity;for (let i = 1; i <= n; i++) {sum = Math.max(sum, p[i] + cut_rod(p, n - i))}return sum;
}
let p = [0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30];
console.log(cut_rod(p, 5)); //13

然而,以上代码一旦输入规模变大,程序运行时间就会变得相当长。以n=4为例,当我们对整个递归过程展开是,它所做的工作量如下:

回过头看,会发现整个过程进行了大量的重复计算,严重浪费了效率。
接下来展示如何将它转换为一个更高效的动态规划算法。动态规划方法对每个子问题只求解一次,并将结果保存下来。如果随后在此需要此子问题的解,无需重新计算,只需查找保存的结果。有两种方法:

  1. 带备忘的自顶向下法
    此方法仍然按照自然的递归形式编程,但过程中会保存每个子问题的解。
function memorized_cut_rod(p,n){let arr = new Array(n);arr.fill(-1);function _memorized_cut_rod(p, n, arr){if(arr[n] >= 0){return arr[n];}if(n == 0){return 0;}let sum = -Infinity;for (let i = 1; i <= n; i++) {sum = Math.max(sum, p[i] + _memorized_cut_rod(p, n - i, arr))}arr[n] = sum;return sum;}return _memorized_cut_rod(p, n, arr)
}
let p = [0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30];
console.log(memorized_cut_rod(p, 5)); //13

对照之前的代码,动态规划方法付出了额外的内存空间,但是节省了非常多的时间。

  1. 自底向上法
    这种方法一般需要恰当定义子问题“规模”的概念,使得任何子问题的求解都只依赖于“更小的”子问题的求解。
function bottom_up_cut_rod(p, n) {let arr = new Array(n);// 长度为0时的解为0arr[0] = 0;for (let i = 1; i <= n; i++) {let sum = -Infinity;for (let j = 1; j <= i; j++) {// n = 1时,i-j = 0,arr[0]已知为0// n = 2时,i-j = 1、0,arr[1]、arr[0]均已知// n = 3时,i-j = 2、1、0,arr[2]、arr[1]、arr[0]均已知sum = Math.max(sum, p[j] + arr[i - j]);}// 数组中记录子问题的解arr[i] = sum;}return arr[n];
}
let p = [0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30];
console.log(bottom_up_cut_rod(p, 5)); //13

此方法采用子问题的自然顺序,若j < i,则规模为j的子问题比规模为i的子问题更小,因此,过程依次求解规模为i = 0,1,…,n的子问题。

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

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

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

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

    动态规划钢条切割问题 动态规划(dynamic programming)与分治法类似.分治策略将问题划分为互不相交的子问题,递归求解子问题,再将子问题进行组合,求解原问题.动态规划应用于子问题重叠的情 ...

  3. 动态规划—钢条切割问题与01背包问题

    目录 1.钢条切割问题 第一种求最优解方案: 第二种求最优解方案: 第一种方法是 带备忘的自顶向下法 第二种方法是 自底向上法 2.01背包问题 1,穷举法(把所有情况列出来,比较得到 总价值最大的情 ...

  4. 算法导论-动态规划-钢条切割问题

    文章目录 一.钢条切割定义 二.具体步骤 1.思考 2.代码思考 3.动态规划求解 4.伪代码 三:总结: 一.钢条切割定义 图为价格表 给定一段长度是n的钢条和一个价格表,求切割方案使得收益达到最大 ...

  5. 动态规划-钢条切割(java)

    数据结构与算法系列源代码:https://github.com/ThinerZQ/AllAlgorithmInJava 本文源代码:https://github.com/ThinerZQ/AllAlg ...

  6. 动态规划——钢条切割

    有一根钢条,和他的长度价格表,真么样切割才能使得售出的钢条收益最大. 不考虑钢条的切割损耗. 输入n 表示钢条的长度 价格表p[i] 表示长度为i的钢条出售的价格 ------------------ ...

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

    int BottomUpCutRod(int p[],int n) { int *r=new int[n+1]; r[0]=0; for (int j=1;j<=n;j++) { int q=- ...

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

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

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

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

最新文章

  1. Linux命令find的35个实例
  2. Git根据文件名字查询修改文件内容
  3. python入门区块链技术_区块链入门教程
  4. Dispatch Queue 之 Invoke 当前队列
  5. 10分钟用python编写贪吃蛇小游戏_牛得一批!10分钟用Python编写一个贪吃蛇小游戏...
  6. JS面向对象的实现和原理
  7. mysql报错ERROR 1045 (28000)
  8. JAVA设置流中当前位置_java文件流的问题!急
  9. oracle表和对象基础维护笔记
  10. python--gevent协程及协程概念
  11. PHP系列(十三)PHP会话控制
  12. JAVA常见算法题(四)
  13. Talib技术因子详解(八)
  14. 学习《软件评测师教程》
  15. go 获取本机ip地址
  16. 恢复扩容U盘实际容量 检查正版U盘 U盘量产工具 U盘修复工具使用方法
  17. 向日葵设置开机自启动
  18. 程序员 大牛 面试
  19. 实验:非骨干区域通过虚链路穿越非骨干区域连接骨干区域实现互联互通
  20. 计算机二级ppt云计算,2021年全国计算机等级考试二级officeppt演示文稿题目.docx

热门文章

  1. 获取注册表信息-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography的MachineGuid的值
  2. Qt5.9/C++架构实例(一个简单的MCV架构应用实例)
  3. 2023 XL软件库App后端源码 可自定义易支付 完整版
  4. 【机器学习】补完计划
  5. unsw计算机科学的挂科率,2020年新南威尔士大学研究生挂科率
  6. 新南威尔士大学计算机博士申请,2020年新南威尔士大学博士申请时间
  7. java 数学公式解析框架有哪些_开源工具 | 推荐几个Gitee火热Java项目
  8. 华为手机不能支持5G,研发创新科技解决,M国的做法落空
  9. c语言 统计已初始化的二维数组a[3][4]中非零元素的个数(用指针实现)
  10. 平面解析几何----圆锥曲线焦点弦上焦半径的倒数和为ep分之2的初等几何证明