动态规划学习笔记--对于钢条切割方案的思考

1.问题描述

对一个长为n的钢条,给出不同长度钢条对应的单价,求出如何切割能使得该钢条的收益最大化。

2.问题解析

(1)暴力法

找出所有切割方案(共2^(n-1)种),计算出每种切割方案的收益,求最大值。

时间复杂度:O(2^(n-1))

(2)动态规划

这一问题是《算法导论》中,讲解动态规划的例题。

为什么这题能够用动态规划解决呢?

动态规划是用来解决具有以下性质的问题的:

1.最优子结构

2.重复子问题

这两个性质,显然前者更为重要,而后者没有也可以用动态规划解决(我现在这么认为)。

动态规划的正确性证明

为什么这一题具有最优子结构性质呢?

对于最优解(最优切割方案),它切割下来的每一段钢条都应该是对于该长度最优的切割方案,否则,继续切割能获得更优的解。

注意:这里的最优子结构应看做一种“必要非充分条件”。

最优子结构组合起来的一定是最优解吗?显然不是!

举个最极端的例子,如果把长为n的钢条切割为n个长为1的钢条,那么每段钢条都是该长度最优的切割方案了。而我们显然不能认为最优的切割方案就是这样。

那么要如何达到“充分”呢?

由于最优子结构是必要条件,因此正确答案一定存在于所有的最优子结构组合中。如何找到它,一个简单的想法如下:

再次用暴力法,对每种最优子结构的组合进行遍历,找到最优解!

现在有了“必要”,有了“充分”,我们确保了动态规划解决这个问题的正确性。

具体动态规划方案设计中的难点

分析到这里,我们想要解决这个问题,还有一个难点,那么就是如何找出所有最优子结构的组合!这个难点也就是动态规划中,状态如何表示,以及状态如何转移的难点。

突破点:用子问题定义最优解。

最优解与它的子问题的关系可以分类为如下几种:

1.仅与比它的规模小1的子问题相关。//提示:这与重复子结构不是矛盾的,在做某些题的时候我们可以看到,如最长公共子串。

2.与满足特定条件的多个子问题相关。

3.与所有子问题相关。

到了这里我们已经感受到动态规划的灵活度之高了,很难找到一种套路。

对3种关系进行思考,我们初步假定这个问题适用第3种关系,这里仅提供一个不完善的思路。

每个最优子结构组合可能有多个自问题,我们希望尽量减少最优子结构组合的数量,因此我们思考是否一个最优子结构组合可以只包含一个子问题。

本题中,假设规模为n的最优解为d(n),按照上面的想法,我们发现可以列出它的所有最优子结构组合:

d(1)+p(n-1)

d(2)+p(n-2)

……

d(n)+p(0)

最后,我们只需要找出上面列出的组合的最大值即可。

时间: 2024-08-02 23:08:09

动态规划学习笔记--对于钢条切割方案的思考的相关文章

算法导论读书笔记之钢条切割问题

算法导论读书笔记之钢条切割问题 巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo) 给定一段长度为n英寸的钢条和一个价格表 pi (i=1,2, -,n),求切割钢条的方案,使得销售收益rn最大.注意,如果长度为n英寸的钢条价格pn足够大,最优解可能就是完全不需要切割. 若钢条的长度为i,则钢条的价格为Pi,如何对给定长度的钢条进行切割能得到最大收益? 长度i   1   2    3   4     5      6     7     8  

动态规划入门一:钢条切割问题

问题: 求解一个钢条如何切割钢条的简单问题. 给定一段长度为n英寸的钢条和一个价格表pi(i=1, 2, ..., n),求切割钢条方案,使得销售收益rn最大.注意,如果长度为n英寸的钢条的价格pn足够大,最优解可能就是完全不需要切割. 输入: 长度i | 1 2 3 4 5 6 7 8 9 10 价格pi | 1 5 8 9 10 17 17 20 24 30 输出: 切割方案. Reference: <算法导论>原书第3版中文版 第15章动态规划 原文地址:https://www.cnbl

动态规划(一)钢条切割

简介 什么是动态规划 答:动态规划与分治法相似,都是通过组合子问题的解来求解原问题.他们之间的不同是,分治法将问题划分为互不相交的子问题,而动态规划应用于子问题重合的情况.使用分治法求解子问题重合的问题,会做许多不必要的工作,动态规划将已经求解的子问题保存到一张表格中,从而避免了反复求解重合子问题的情况. 动态规划常用来解决什么问题 答:最优化问题.最优化问题可以有很多可行解,每个解都有一个值,我们希望寻找具有最优值的解,最大或最小.我们称这样的解是问题的一个最优解(最优解可以有多个). 设计动

动态规划学习笔记(不定期更新)

最近刚开始接触动态规划(Dynamic Programming)算法,之前略有耳闻,一直觉得DP非常之高大上,看了某些题的DP解法也是云里雾里,哇擦?!这么几行代码就解决了?怎么全是数组操作?时间复杂度也很低的样子.其实不然,当我真正开始学习动态规划的时候才发现这货没那么玄乎. 把我对DP浅显的理解总结为以下几点: 1.空间换时间. 2.找到状态. 3.找到状态转移方程. 动态规划是通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以递推(或者说分治)的方式去解决.为了能够快速的不重复的计

Unity学习笔记:Sprite切割图片及使用

导入一张大图和导入多张小图哪种更好?  --  这不是本文的内容! 一般动画用的帧图都是在一张大图里的. 切割 1.拖拽一张大图进入Assets/Resources目录下. 注意:只有在Resources目录下的资源才能在代码中被Resources类获取到. 2.进入切割 点击[Sprite Editor]按钮,显示切割页面.仅介绍网格切割(Type = Grid By Cell Size),其它形式以后再学. Pixel Size 单元格尺寸: Offse 单元格内的左侧(x)和上方(y)的留

动态规划学习笔记

案例1.最长回文序列一个字符串有许多子序列,比如字符串abcfgbda,它的子序列有a.bfg.bfgbd,在这些子序列中肯定有回文字符串.现在要对任意字符串求其最长的回文子序列.注意,本文不是解决最长回文子串,回文子串是连续的,回文子序列是不连续的.字符串abcfgbda的最长回文子序列为abcba,长度为5.输入:包含若干行,每行有一个字符串,字符串由大小写字母构成,长度不超过100.输出:对每个输入,输出一行,该行有一个整数,表示最长回文子序列的长度. ExampleInput: aabc

Effective C++学习笔记之对RAII思想的思考

 在阅读  Effective C++时,对RAII开始不理解,现总结如下: RAII是Resource acquisition is initialization的缩写形式,即"资源获取就是初始化",是C++等编程语言常用的管理资源.避免内存泄露的方法.它保证在任何情况下,使用对象时先构造对象,最后析构对象. 根据RAII 对资源的所有权可分为常性类型和变性类型,代表者分别是boost::shared_ptr和std::auto_ptr:从所管资源的初始化位置上可分为外部初始化类

动态规划之钢条切割问题

/* * 钢条切割方案自底向上 */ public class CutRodBottom2Up { //钢条价格表 private final int[] price={1,5,8,9,10,17,17,20,24,30}; public static void main(String[] args) { new CutRodBottom2Up().start(); } private void start() { for(int i=1;i<=10;i++) { //打印一种最优方案 prin

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

动态规划算法概述 动态规划(dynamic programming)1是一种与分治方法很像的方法,都是通过组合子问题的解来求解原问题.不同之处在于,动态规划用于子问题重叠的情况,比如我们学过的斐波那契数列.在斐波那契数列的求解问题中,我们经常要对一个公共子问题进行多次求解,而动态规划算法,则对每个子问题只求解一次,将其解保存在一个表格中,从而避免了大量的冗余计算量. 动态规划算法常用于寻找最优解问题(optimization problem).而其规划大概可分为四步: 1.刻画一个最优解的结构特