动态规划——钢管问题(算法导论经典问题)

来源:互联网 发布:世界观宏大的小说知乎 编辑:程序博客网 时间:2024/04/30 22:42
绪论
关于动态规划,博主尚在学习中,但总的来说动态规划和分治算法有一定的相似性,分而治之,复杂问题到简单问题的分解,而动态规划较之更为优化,在本问题当中对于动态规划的设计有两种:
1、带备忘的自顶向下法
在分治法的基础上,将每个分解到的小问题的解存储到一个数组里,等到下次调用时就可以直接利用,而不需要再算一次,从而节省了时间。
2、自底向上法
将子问题按照从小到大的顺序进行求解,每一个子问题的解都依赖与比它更小的子问题的解

问题简述
一公司售出一段长为i英寸的钢条的价格为p[i](i=1,2,3,... ...),钢条的长度均为整英寸,下表为其价格单:
现在给定一段n英寸长的钢条,求其切割方案,使得最终价格r[n]为最大
问题分析
假设n英寸长的钢管的最优收益为r[n],未进行切割的价格为p[n],将n英寸的钢管看做两部分,一部分的长度已定为i英寸的价格p[i],而另一部分为n-i英寸的最优收益r[n-i],故而r[n]=max(p[n], p[1]+r[n-1] , p[2]+r[n-2],.......,p[n-1]+r[1])
譬如,已知1~3英寸的钢管的最好切割方案就是不进行切割,若现有4英寸的钢管,第一部分若为2英寸,则根据价格表可以知道其价格为5,第二部分为2英寸,由于2英寸的最佳切割方案为不切割故而其值亦为5。
问题解决
1、分治法
在函数cut_rod中传入价格表p,及要切割的尺寸n,严格按照问题分析中得到的式子r[n]=max(p[n], p[1]+r[n-1] , p[2]+r[n-2],.......,p[n-1]+r[1])进行递归求解。
注意:p是下标从0开始的数组——q=max(q,p[i-1]+cut_rod(p,n-i))!!!
这是典型的分治算法,分而治之,由难到易!!
2、带备忘的自顶向下法
绪论中已经简单介绍了带备忘的自顶向下法,在分治法的问题分析中已经将大体思路理清楚了,观察函数cut_rod,发现,如果在函数中加入一个数组用来记录每一次递归的返回值q,即n英寸的钢管的最佳收益,等到下一次递归时,可以直接调用r数组中的值,如此一来节省了时间,这便是带备忘的自顶向下法

3、自底向上法
自底向上法的核心是子问题的由小到大的依次解决,在函数bottm_up_cut_rod中,我们依旧传入价格表数组p,与需要计算的英寸数。重点部分在于最佳受益数组r的设定。
在自底向上的过程中,每一个子问题的解决都依赖于比它更小的子问题,那么,我们便从最小子问题开始求解,故而设定了一个双重循环,以此来求出r数组中的每一个值。

:博主只是个初学者,以上只是个人观点,如有不清楚的,或者有错误的希望大家能够指出或者私信,3Q,么么哒

0 0