经典动态规划学习记录

经典动态规划学习记录

动态规划本质是一种用空间换时间的优化方法,通常来优化可以暴力搜索求解的问题,也就是去冗余,把之前计算过的存下来,而且是规定了递归的计算顺序,从简单基本的出发,依次计算(这也是他优于记忆搜索的地方)。方法大概如下:
1.首先能明白暴力递归怎么实现(重要);
2.找到函数中可以代表递归过程的参数;
3.参数为key,结果为value,存入dict中,方便以后拿来用(记忆搜索);
4.进一步整理状态关系,如果二维先把第一行和第一列算出来,之后找到状态方程(后续可能还可以优化)

学习过程中看了很多博文和理论,感觉理解还是一知半解,后来觉得自己是遇到这类问题最基本的暴力递归这里就没有想清楚,遇到的笔试题基本都不会,还是记录下经典的几道题吧(因为经典,所以需要记住动态规划过程)。


1.最小路径的和

输入:一个二维矩阵,从矩阵左上角(0,0)开始走,走到右下角,每次只能向右或向下走,则求所有路径中路径和最小的是多少

[
[1,3,5,9],
[8,1,3,4],
[5,0,6,1],
[8,8,4,0]
]
输出:12(1-3-1-0-6-1-0)

思路:
1.生成和输入矩阵大小一样的M*N矩阵;dp[i][j]的值为从(0,0)位置到(i,j)位置的最小路径和;
2.对第一行元素来说,只能不断右移,所以第一行就是不断右移相加,第一列同理

[1,4,9,18],
[4       ],
[14      ],
[22      ]

3.考虑完dp[i][0]和dp[0][j],现在考虑dp[i][j]
因为每个位置都有两种走法,所以对于dp[i][j]位置来说,他应该是当前位置的值加上min(dp[i-1][j],dp[i][j-1]),也就是dp[i][j] = m[i][j] + min(dp[i-1][j],dp[i][j-1])

思路大概就是这样,这个相对比较好理解,代码实现如下

def findMinLength(array):

    rows = len(array)
    cols = len(array[0])

    for i in range(1,rows):  #第一列各位置初始化
        array[i][0] += array[i-1][0]
    for j in range(1,cols): #第一行各位置初始化
        array[0][j] += array[0][j-1]

    for i in range(1,rows): #按顺序计算每个位置最小值存入array[i][j]
        for j in range(1,cols):
            array[i][j] += min(array[i-1][j],array[i][j-1])

    print(array[-1][-1])

2.跳台阶问题

问题描述:有一楼梯共m级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第m级,共有多少走法?
注:规定从一级到一级有0种走法。

思路很简单:f(n) = f(n-1)+f(n-2) 注意这里默认开始在第一级,斐波那契数列稍微条件变了一点

def jump(n):
    res = [0,1,2]
    while len(res)<n:
        res.append((res[-1]+res[-2]))
    print(res[n-1])
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值