动态规划-钢条切割(java)

本文通过钢条切割问题介绍动态规划的概念和应用。详细分析了递归法的效率问题,然后探讨了带备忘的自顶向下法和自底向上法,这两种方法的时间复杂度均为O(n^2),但自底向上法更优。最后,提供了求解切割方案的代码,并总结了三种方法的优劣。
摘要由CSDN通过智能技术生成

数据结构与算法系列源代码:https://github.com/ThinerZQ/AllAlgorithmInJava
本文源代码:https://github.com/ThinerZQ/AllAlgorithmInJava/blob/master/src/main/java/com/zq/algorithm/dynamicprogrammin/SteelBar.java

如果代码链接失效了,麻烦评论给我。

动态规划分治法相似,都是通过组合子问题的解来求解原问题。

分治法将问题划分为不互相交子问题,递归的求解子问题,再将他们组合起来,求出原问题的解。

与之相反,动态规划应用于子问题重叠的情况,即不同的问题具有公共的 子子问题。这种情况下分治法会重复的求解那些公共的子子问题。而动态规划算法对每个子子问题只求解一次,将其存放在某一个表格中,无需每次求解一个子子问题时都重新计算,避免了不必要的计算工作,特别是当问题规模比较大的时候,在时间上有显著的区别

动态规划用来求解最优化问题。这类问题可以有很多可行的解,每个解都有一个值,我们希望需找具有最优值(最大或最小)的解。当然可能同时存在多个最优解(同时最大,或同时最小),动态规划只要求找到其中一个就好了。

这里我们用算法导论里面的钢条切割为例子

切钢条:假如Serling公司出售一段长度为 i 英寸的钢条的价格为 pi( i =1,2,3,4…单位问美元)。钢条的长度为整英寸。

下表是一个价格表

长度i 1 2 3 4 5 6 7 8 9
价格pi 1 5 8 9 10 17 17 20 24

假设Serling公司进了一批长度为10的钢条,那么怎么切割才能使利益最大呢,长度为 9 , 8 呢?

对于上述价格表样例,我们可以观察出所有最优收益值Ri及对应的最优解方案:

最优值 切割方案
R1 = 1 切割方案1 = 1(无切割)
R2 = 5 切割方案2 = 2(无切割)
R3 = 8 切割方案3 = 3(无切割)
R4 = 10 切割方案4 = 2 + 2
R5 = 13 切割方案5 = 2 + 3
R6 = 17 切割方案6 = 6(无切割)
R7 = 18 切割方案7 = 1 + 6或7 = 2 + 2 + 3
R8 = 22 切割方案8 = 2 + 6
R9 = 25 切割方案9 = 3 + 6
R10 = 30 切割方案10 = 10(无切割)


更一般地,对于Rn(n >= 1),我们可以用更短的钢条的最优切割收益来描述它:

Rn = max(Pn, R1 + Rn-1, R2 + Rn-2,…,Rn-1 + R1)

首先将钢条切割为长度为i和n - i两段,接着求解这两段的最优切割收益Ri和Rn - i(每种方案的最优收益为两段的最优收益之和),由于无法预知哪种方案会获得最优收益,我们必须考察所有可能的i,选取其中收益最大者。如果直接出售原钢条会获得最大收益,我们当然可以选择不做任何切割。

注意到,为了求解规模为n的原问题,我们先求解形式完全一样,但是规模更小的子问题。当完成首次切割之后,我们将两段钢条看成两个同等的钢条切割问题实例,通过组合两个问题的最优解,并在所有可能的两段切割方案中选择组合收益最大值,构成原问题的最优解,我们称这样的问题满足最优子结构性质问题的最优解是由相关子问题的最优解组和而成的,这些子问题可以独立求解。

分析到这里,假设现在出售10英寸的钢条,应该怎么切割呢?为了方便分析,我们使用钢条长度=4来分析问题

1、解法:

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值