动态规划笔记

动态规划是运筹学的一个分支,是求解决策过程最优化的过程。20世纪中期,美国数学家贝尔曼等在研究多阶段决策过程的优化问题时,提出了最优化原理,从而创建了动态规划。

动态规划在经济管理,生产调度,工程技术和最优控制等方面得到了广泛的应用。例如,最短路线、库存管理、资源分配、排序、装载等问题,用动态规划方法比其他方法求解更为方便。

虽然动态规划主要用于求解以时间划分阶段的动态过程的优化问题,但是一些与时间无关的静态规划,只要认为的引入时间因素,把它视为过阶段决策过程,也可以用动态规划方法方便的求解。

基本思想

动态规划算法用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。动态规划算法与分治发类似其基本思想也是将待求解的问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。若用分治法来解决问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次,如果我们能够保持已解决的子问题的答案。不管该子问题以后是否会被用到,只要它被计算过,就将其结果填入表中。这就是动态规划的基本思路。

 基本概念

        多阶段决策问题

        如果一类活动过程可以分为若干个互相联系的阶段,在每一个阶段都需做出决策,一个阶段的决策确定以后,常常影响到下一个阶段的决策,从而就完全确定了一个过程的活动路线,则称它为多阶段决策问题。

        各个阶段的决策构成一个决策序列,称其为一个策略。每一个阶段都有若干个决策可供选择,因而就有许多策略供我们选择,对应于一个策略可以确定活动的效果,这个效果可以用数量来确定。策略不同,效果也不同,多阶段决策问题,就是要在可以抉择的那些策略中间,选择一个最优策略,使在预定的标准下达到最好的效果。

动态规划问题案例详解

动态规划详解_Ashley zhao的博客-CSDN博客_动态规划

案例1:简单的一维DP

一只青蛙一次可以跳上一级台阶,也可以跳上两级台阶。求该青蛙跳上一个n级台阶总共有多少种跳法。

  1. 定义数组

        定义dp[i]的含义为跳上一个级的台阶总共有dp[i]种跳法。

     2. 把一个规模比较大的问题分成几个规模比较小的问题。

        即dp[n]的规模为n,比它规模小的是n-1, n-2, ... 也就是说,dp[n]一定和dp[n-1], dp[n-2]……存在某种关系。对于此题,因为青蛙一次可以跳一级,可以选择跳两级,所以青蛙到达第n级台阶有两种方式

        一种是从第n-1级跳上来

        一种是从第n-2级跳上来

        所以有dp[n] = dp[n-1] + dp[n-2]

     3. 找到初始条件

        显然,dp[0] = 0, dp[1] = 1,  dp[2] = 2

        结题代码如下:

class Solution:
    def jump_frog(self, n):
        if n<=2:
            return n
        else:
            a = 1
            b = 2
            for i in range(3,n+1):
                c = a + b
                a = b
                b = c
            return c

案例 2: 二维数组的DP

一个机器人位于一个m*n的网格左上角。机器人每次只能向下或者向右移动一步。机器人试图到达网格的右下角。问总共有多少条不同的路径?(说明:m,n值均不超过100)

1. 定义数组元素

        定义dp[i][j] : 当机器人从左上角走到(i,j)这个位置时,一共有dp[i][j]中路径。则本题的目标为dp[m-1][n-1].

2. 找出数组关系式

        机器人要达到(i,j)这个位置,可以向下走,或者向右走,所以有两种方式到达

        一种是从 (i-1, j) 这个位置走一步到达(是(i,j)正上方的那一格
        一种是从(i, j - 1) 这个位置走一步到达(是(i,j)正前方的那一格

        所以有关系式 dp[i,][j] = dp[ i-1 ][ j ] + dp[ i ][ j-1]

3. 找出初始值

        dp[0][0,1,....n-1] = 1

        dp[0,1,...m-1][0] = 1

 

class Solution:
    def uniquePaths(self, m: int, n: int) -> int:
        f = [[1] * n] + [[1] + [0] * (n - 1) for _ in range(m - 1)]
        print(f)
        for i in range(1, m):
            for j in range(1, n):
                f[i][j] = f[i - 1][j] + f[i][j - 1]
        return f[m - 1][n - 1]

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/unique-paths/solution/bu-tong-lu-jing-by-leetcode-solution-hzjf/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值