动态规划,不用递归,也能酷酷解决!


前言

学无止境,笔勤不辍。前面,我们谈到了算法中一种很重要的思想:分治,它的运用实在是十分广泛,不仅可以用于排序,同时也可运用到动态规划问题中。本文将会由一个爬梯子的问题/斐波拉契数开始,到流水线最短挑选,分享一下动态规划问题,后续还会讲矩阵链乘。


一、爬梯子/斐波拉契数

小A喜欢在楼梯上跳来跳去,但年幼的他一次只能走上1阶或者2阶。 现在一共有N阶台阶,请你计算一下小明从第0阶到第N阶共有几种走法。
为了简化问题,我们将N设置为10展开讨论。
在这里插入图片描述
图有点丑哈哈哈哈,将就理解一下
若我们要求登上第10级台阶的方法数,可以是第8级台阶直接上2级(因为如果第8级上1级到第九级,然后再上1级到第10级,其实和后面的有重复),也可以是第9级台阶上1阶,那也就是说,我们只要知道了上第8级的方法数,和上第9级台阶的方法数,那上第10级台阶的方法数就是它们之和:
在这里插入图片描述
然后如果台阶数是1,我们很容易知道只有1种方法,台阶数是2,则有2种,那么整体的递归表达式就可以是:
在这里插入图片描述
然后我们就可以递归调用了
这里在介绍一种优化的方式,就是创建一个数组从第三个数开始由前两个数,两两相加,当n>=3的时候,数组下标为n-1的就是我们要求的结果
上代码:

 def fib(self, n):
        """
        """
        if n==0:
            return 0
        if n ==1:
            return 1
        #return self.fib(n-1)+self.fib(n-2) 方法一:递归调用
        num = [0,1]
        for i in range(len(num),n+1):
            num.append(num[i-2]+num[i-1])
        print(num)
        return num[n]

这里的下标要注意。

二、流水线最短挑选

在一工厂里有两条装配线并行生成汽车, lines 1 and 2
每条装配线有 n 个装配站 Si,1…Si,n , i =1, 2
设对于每个 j, S1, j 和S2, j 的功能相同, 但装配时间不同,对Si, j 的装配时间为 ai, j
汽车装配可以从一条装配线移到另一条装配线,从装配站Si, j 移到到另一条装配线上的时间为ti, j , i=1, 2 and j =1, 2, … , n-1
汽车进入装配线的时间为 ei ,汽车离开装配线的时间为 xi
问:确定在装配线1内选择哪些站,以及在装配线2内选择哪些站,以使汽车装配的总时间最小。
首先我们上图理解一下这个意思:
在这里插入图片描述
我们要求找到总时间最小的线路,其实就是要找到,到达S1,n 和S2,n的最短时间的路线。
以S1,n为例:
到达S1,n的路线有两条,一条是S1,n-1 加上时间a1,n 另一条是 S2,n 加上转移时间t2,n-1 加上时间a1,n,两者比较取最小值。因此我们只要知道到达S1,n-1和到达S2,n-1的最短路径,就挑选最短线路了,因此,S1,j的递归表达式就可以写成:
在这里插入图片描述
同理S2,j的表达式:
在这里插入图片描述
最终:
在这里插入图片描述
然后这里写一段伪代码供大家参考:

FASTEST-WAY(a,t,e,x,n)
 f1[1] ← e1+ a1,1
 f2[1]← e2 + a2,1
 //按照递推公式来就可以
  for j←2 to n
     do if f1[j-1]+a1,j <= f2[j-1]+t2,j-1+a1,j
     then f1[j]← f1[j-1]+a1,j
     l1[j]1//是为了重建路线的
    else f1[j]← f2[j-1]+t2,j-1+a1,j
        l1[j]2
   if f2[j-1]+a2,j <= f1[j-1]+t1,j-1+a2,j
   then f2[j]← f2[j-1]+a1,j
   l2[j]2
  else f2[j]←f1[j-1]+t1,j-1+a2,j
  l2[j]1
 if f1[n]+x1<=f2[n]+x2
   then f* = f1[n]+x1
   l*=1
 else f* = f2[n]+x2
 l* =2

tips:动态规划一般都可以用递归调用解决,但是我们一般不用hahaha!
用数组的方式可以使得算法的时间复杂度降低到O(N)!!!


总结

以上就是今天要讲的内容,动态规划还是蛮有意思的,接下去笔者也会更新更多的有关动态规划的例子,请大家关注一波~~~

  • 16
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值