动态规划(dynamic programming)就是把问题分解成一个个的子问题,然后对子问题进行求解。下面用通俗易懂的语言来解释下动态规划中关于重构解的理解。既保存最优切割收益也保存切割方案!
重构解
1、保存最优切割收益也保存切割方案的算法
用 s[ j ] = i 来表示,长度为 j 的钢条(当然在构建模型的时候也可以是其他含义)所得的最优解为 i 。
上述思想写成BOTTOM-UP-CUT-ROD扩展版本如下:
其中,p[ i ]:长度为 i 的钢条的价格;q:记录长度为 j 的钢条最优收益;r[ j ]:保存每种情况的 q;s:整根钢条的切割方案
- 第3句:求每种长度的情况的钢条第一段切割的最优解。
- 第4句:初始化最优解值为负无穷。
- 第5句:从长度为 1 开始遍历,一直到整根钢条长度。计算出第一段长度该切割成多长才能获得最优解,保存在
s [ j ]=i
中。 - 第6句:
q
代表最优解收益,p[ i ] + r[ j - i ]
表示切割下的第一段长度为i
,剩下钢条长度j - i
的最大收益为r[ j - i ]
,因此总收益即为p[ i ] + r[ j - i ]
。因此,当q<p[ i ] + r[ j - i ]
的时候,更新最优情况,s[ j ] = i
即切割第一段长度为i
时获益最大。 - 当遍历完所有的情况,即可知道当前长度为
j
的钢条第一段切割多长可获得最优收益。
因此,在本算法中,不仅保存了最优收益值p
,还保存了第一段切割长度(递归操作后,即可知道总的切割方案了),也即第10 句返回的r
(最大收益)和s
(切割方案)。
上述方案和BOTTOM-UP-CUT-ROD很相似,差别只是在第一行创建了数组s(第一句),并将求解规模为 j 的子问题时,将第一段钢条的最优切割长度 i 保存在s[ j ]中了(第8句)。
2、调用上述函数并输出钢条切割方案 s 、最大收益 r
例如:长度为10 的钢条有如下最优切割情况,调用BOTTOM-UP-CUT-ROD(p,10)。
从上述表格可以看出,长度为10 的钢条不用切割即可获得最大收益。若长度为7呢?可以看出是1,6的切割方案最合理。
参考资料:
[1].《算法导论》第三版