动态规划之钢条切割问题
来源:互联网 发布:网络剧备案查询 编辑:程序博客网 时间:2024/06/06 08:24
钢条切割问题:
某公司购买长钢条,将其切割为短钢条,价格案例如下:
给定一个长度为n英寸的钢条,怎么切割使得销售收益最大。
最优子结构:问题的最优解由相关子问题的最优解组合而成,而这些子问题可以独立求解。
钢条切割的简单递归方法:我们将钢条从左边切割下长度为i的一段,只对右边剩下的长度为n-i的一段继续进行切割(递归求解),对左边的一段则不再进行切割。
即问题分解的方式为:将长度为n的钢条分解为左边开始一段,以及剩余部分 继续分解的结果。
动态规划有两种等价的实现方法:
1、带备忘的自顶向下法:此方法扔按自然的递归形式编写过程,但过程会保存每个子问题的解,通常保存在一个数组或散列表中。当需要一个问题的解时,过程首先检查是否已经保存过此解。如果是,则返回保存的值,从而节省了计算时间;否则,按通常方式计算这个子问题,“带备忘”的意思就是记住了之前计算的结果
public static int memoized_cut_rod(int[] p,int n){int result;int[] res=new int[n+1]; //res备忘数组for(int i=0;i<res.length;i++){res[i]=-1;}result=cut_rod(p, n, res);return result;}public static int cut_rod(int[] p,int n,int[] res){int q=-1;if(n==0)q=0;if(res[n]>=0)return res[n];else { for(int i=1;i<=n;i++) { q=Math.max(q, p[i]+cut_rod(p, n-i, res)); }}res[n]=q;return q;}
2、自底向上法:这种方法一般需要恰当定义子问题“规模”的概念,使得任何子问题的求解都只依赖于“更小的”子问题的求解,因而我们可以将子问题按规模排序,按由小到大的顺序进行求解。当求解某个子问题时,它所依赖的更小的子问题已经求解完毕,结果已经保存。每个子问题只需求解一次,当我们求解它(也就是第一次遇到它)时,它的所有前提子问题都已求解完成。
public static int bottom_up_cut_rod(int[] p,int n){int[] res=new int[n+1];res[0]=0;int q=-1;for(int i=1;i<=n;i++){res[i]=-9999;for(int j=1;j<=i;j++){q=Math.max(q, p[j]+res[i-j]);}res[i]=q;}return res[n];}
两种方法得到的算法具有相同的渐进运行时间,仅有的差异是在某些特殊情况下,自顶向下的方法并未真正递归考察所有的的子问题,由于没有频繁的递归函数调用的开销,自底向上方法的时间复杂性函数通常具有更小的系数。
代码汇总:
package lianxi;public class dp_cutrod {public static int memoized_cut_rod(int[] p,int n){int result;int[] res=new int[n+1]; //res备忘数组for(int i=0;i<res.length;i++){res[i]=-1;}result=cut_rod(p, n, res);return result;}public static int cut_rod(int[] p,int n,int[] res){int q=-1;if(n==0)q=0;if(res[n]>=0)return res[n];else { for(int i=1;i<=n;i++) { q=Math.max(q, p[i]+cut_rod(p, n-i, res)); }}res[n]=q;return q;}public static int bottom_up_cut_rod(int[] p,int n){int[] res=new int[n+1];res[0]=0;int q=-1;for(int i=1;i<=n;i++){res[i]=-9999;for(int j=1;j<=i;j++){q=Math.max(q, p[j]+res[i-j]);}res[i]=q;}return res[n];}public static void main(String[] args){int[] p={0,1,5,8,9,10,17,17,20,24,30};int n=9;int result=memoized_cut_rod(p, n);//调用带备忘的自顶向下法int result2=bottom_up_cut_rod(p, n);//调用自底向上法System.out.print(result);System.out.print(result2);}}
输出结果为:25
阅读全文
1 0
- 动态规划问题之钢条切割
- 动态规划之钢条切割问题
- 动态规划之钢条切割问题
- 动态规划之钢条切割问题
- 动态规划之钢条切割问题
- 动态规划问题之 钢条切割
- 动态规划之钢条切割问题
- 动态规划之钢条切割问题
- 动态规划-钢条切割问题
- 动态规划:钢条切割问题
- 【动态规划】钢条切割问题
- 动态规划--钢条切割问题
- 动态规划 钢条切割问题
- 动态规划 钢条切割问题
- 动态规划-钢条切割问题
- 动态规划之切割钢条
- 动态规划之钢条切割
- 动态规划之钢条切割
- 深度学习框架
- Ubuntu安装R语言
- python中遇到的问题总结
- java使用poi或者jxl实现excel导出之后如何弹出保存提示框
- 更改jar包里的代码
- 动态规划之钢条切割问题
- 采样率
- An express train to reveries CodeForces
- python实现-质数因子
- 获取web项目的绝对路径的方法总结
- ViewPager+小圆点联动
- NOI2015软件包管理器,大力卡常记
- 【唯一分解定理】Sphenic numbers Gym
- MySQL Show命令的用法大全