问题描述:
  公司购买长钢条,将其切割为短钢条进行出售,切割工序本身没有成本支出,公式管理层希望知道最佳的切割方案。假定我们知道公司出售一段长为i英寸的钢条价格为pi;钢条的长度均为整英寸。给定一段长度为n英寸的钢条和一个价格表pi,求切割钢条方案,使得销售收益最大。如果长度为n英寸的钢条的价格足够大,最优解可能就是完全不用切割。
长度:1, 2, 3, 4, 5, 6, 7, 8, 9,10
对应价格:1,5, 8,16,10, 17, 17, 20, 24, 30。

解法一:
  用记忆型递归进行求解:比如一段长度为10的钢条,保留1英寸,将剩下的9英寸进行切割;也可以保留2英寸,将剩下的8英寸进行切割,以此类推。所以递归树的根节点有十个分支。剩下的节点要切割几英寸就有几个分支。由于在进行递归的时候有很多重复的子问题,导致相同的问题进行多次求解;所以为了提高效率可以将递归过程中得到的解进行记录。这称为记忆型递归或者记录型递归。

代码如下:

import java.util.*;public class 钢条切割 {static int[] p = {0, 1, 5, 8, 16, 10, 17, 17, 20, 24, 30};//价格表,第零个位置不用static int[] vs = new int[10+1];//记录表public static void main(String[] args){Scanner scanner = new Scanner(System.in);Arrays.fill(vs, -1);//初始化记录表System.out.println(dfs(10));}private static int dfs(int n) {if(n==0){return 0;}if(vs[n]>=0){//检查是否有记录return vs[n];}else{int v = 0;for(int i=1; i<=n; i++){//保留i英寸v = Math.max(v, p[i] + dfs(n-i));//选出分支中的最大值}vs[n] = v;//进行记录return v;}}
}

解法二:
  用动态规划进行求解;和记忆型递归有些类似。只是建立了一张完整的后返回结果。

代码如下:

import java.util.*;public class 钢条切割 {static int[] p = {0, 1, 5, 8, 16, 10, 17, 17, 20, 24, 30};//价格表,第零个位置不用static int[] dp = new int[10+1];//dp表,下标表示长度,值表示对应长度的最大价值public static void main(String[] args){Scanner scanner = new Scanner(System.in);Arrays.fill(dp, 0);//初始化记录表dp[1] = p[1];//长度为1时无法分割,所以直接可以得出最大价值System.out.println(dpf(10));}/** 动态规划,建立dp表*/private static int dpf(int n) {for(int i=1; i<=n; i++){//求dp[i]int v = 0;for(int j=1; j<=i; j++){v = Math.max(v, p[j]+dp[i-j]);}dp[i] = v;}return dp[n];}}

总结:
  对于这个钢条切割问题最主要是能想到保留一定长度,切割剩下的长度,然后不断递归;以及能考虑到递归过程中会出现多次子问题重复求解。动态规划最重要的是如何用前面的记录推导后面的记录;也就是找出dp公式。

算法导论中的钢条切割问题相关推荐

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

    写下文章来记录下自己学习算法导论的笔记 文章目录 写下文章来记录下自己学习算法导论的笔记 动态规划的目的 设计动态规划算法 钢条切割问题 问题描述 刻画问题结构(建立方程) 递归方程建立 带备忘录的自 ...

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

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

  3. Java实现算法导论中Rabin-Karp字符串匹配算法

    Rabin-Karp算法的思想: 假设子串的长度为M,目标字符串的长度为N 计算子串的hash值 计算目标字符串中每个长度为M的子串的hash值(共需要计算N-M+1次) 比较hash值 如果hash ...

  4. Java实现算法导论中朴素字符串匹配算法

    朴素字符串匹配算法沿着主串滑动子串来循环匹配,算法时间性能是O((n-m+1)m),n是主串长度,m是字串长度,结合算法导论中来理解,具体代码参考: package cn.ansj;public cl ...

  5. Java实现算法导论中Miller-Rabin随机性素数测试

    Miller-Rabin测试: 费马小定理:对于素数p和任意整数a,有ap ≡ a(mod p)(同余).反过来,满足ap ≡ a(mod p),p也几乎一定是素数. 伪素数:如果n是一个正整数,如果 ...

  6. Java实现算法导论中反复平方法模取幂

    在众多的加密算法中都需要进行幂的取模运算,比如在RSA算法中需要计算d=ne mod N,我们称之为幂模算法,其中: N=p*q(p,q为大素数) n为加密数据,n<N e为公钥,d为私钥,满足 ...

  7. Java实现算法导论中求解模线性方程解(基于最大公约数欧几里得扩展算法)

    基于最大公约数欧几里得扩展算法求解算法导论中模线性方程解.具体要结合算法导论中的有关数论算法章节理解,具体代码如下: package cn.ansj;/*假设方程ax=b(mod n)有解,且x0是方 ...

  8. Java实现算法导论中图的广度优先搜索(BFS)和深度优先搜索(DFS)

    对算法导论中图的广度优先搜索(BFS)和深度优先搜索(DFS)用Java实现其中的伪代码算法,案例也采用算法导论中的图. import java.util.ArrayList; import java ...

  9. 算法导论中求解时间复杂度的三种方法

    这一章讲的是递归式(recurrence),递归式是一组等式或不等式,它所描述的函数是用在更小的输入下该函数的值来定义的. 本章讲了三种方法来解递归式,分别是代换法,递归树方法,主方法. 1.代换法( ...

最新文章

  1. 关于修改linux hostname的问题,尤其是redhat 7修改hostname的方式
  2. 使用HSRP和SLB实现服务器群负载均衡和冗余
  3. Android屏幕信息获取
  4. js公共时间戳方法es6
  5. boost::units模块实现三角函数相关的测试程序
  6. CentOS下安装MySQL报安装文件conflicts错误:
  7. 北语20春oracle数据开发2,北语20春《Oracle数据库开发》作业3题目【标准答案】
  8. python 日志模块 日志格式
  9. 中点画线算法画直线----计算机图形学
  10. android中图标怎么改,android的软件图标怎么改
  11. java 字符表 chr3,ASCII码对应表chr(9)、chr(10)、chr(13)、chr(32)、chr(3...
  12. 吴恩达:如何学习机器学习
  13. App Designer中自建回调函数
  14. win10系统解决office16的VBE6EXT.OLB不能被加载的问题
  15. Java递归子集算法(树状结构)的逻辑和实例代码实现 @杨章隐
  16. 四旋翼无人机学习第1节--准备工作
  17. 优达数据分析课程免费分享
  18. python绘图案例——递归绘制分形树
  19. nginx 日志处理goaccess、shell
  20. IOS 实现美图秀秀

热门文章

  1. 教师角色——教育教学视角
  2. v80八核 android6,高通发布骁龙810八核/808六核64位芯片
  3. photoshop制作法线和凹凸贴图
  4. PTA 函数题 堆排序(C语言)
  5. JAVA命名规范(阿里巴巴)及其口语化总结
  6. 一个 Angular 程序员两年多的远程办公经验分享
  7. HCIA课程学习第一天笔记
  8. 基于微信小程序的房屋租赁系统
  9. dpdk Vhost 库
  10. 高一计算机二进制,高中信息技术《二进制及其转换》教学设计 人教版