您的位置:首页 > 其它

初探-动态规划思想

2020-08-12 21:55 197 查看

动态规划(Dynamic Programming)

动态规划原理

  • 基本思想:问题的最优解如果可以由子问题的最优解推导得到,则可以先求解子问题的最优解,在构造原问题的最优解;若子问题有较多的重复出现,则可以自底向上从最终子问题向原问题逐步求解。
  • 使用条件:可分为多个相关子问题,子问题的解被重复使用 Optimal substructure(优化子结构): 一个问题的优化解包含了子问题的优化解
  • 缩小子问题集合,只需那些优化问题中包含的子问题,降低实现复杂性
  • 我们可以自下而上的
  • Subteties(重叠子问题):在问题的求解过程中,很多子问题的解将被多次使用。
  • 动态规划算法的设计步骤:
      分析优化解的结构
    • 递归地定义最优解的代价
    • 自底向上地计算优化解的代价保存之,并获取构造最优解的信息
    • 根据构造最优解的信息构造优化解
  • 动态规划特点:
      把原始问题划分成一系列子问题;
    • 求解每个子问题仅一次,并将其结果保存在一个表中,以后用到时直接存取,不重复计算,节省计算时间
    • 自底向上地计算。
    • 整体问题最优解取决于子问题的最优解(状态转移方程)(将子问题称为状态,最终状态的求解归结为其他状态的求解)

    斐波那契数列

    斐波那契数列大家都很熟悉,而且知道用递归可以很容易的做出来

    0,1,1,2,3,5,8,13,21

    递推公式:F
    =F[n-1]+F[n-2]

    fib(0)=0
    fib(1)=1
    fib(n)=fib(n-1)+fib(n-2)

    递归:


    实现代码:

    int fib(int n){
    if(n<=0){
    return 0
    }else if(n==1){
    return 1
    }else{
    return fib(n-1)+fib(n-2)
    }
    }
    
    #简洁写法
    
    int fib(int n){
    return n<=1 ? n : fib(n-1) + fib(n-2)
    }

    时间复杂度: O(2^n)

    递推:

    实现代码:

    int fib(int n,int[]memo){
    if(n<=0){
    return 0
    }else if(n==1){
    return 1
    }else if (memo
    ){
    memo
    =fib(n-1)+fib(n-2)
    }
    return memo
    
    }

    时间复杂度: O(n)

    走格子

    格子的左上角为入口,右下角为出口,粉红色为路障石头,请问有多少种方法从入口走到出口

    paths(start,end)=paths(A,end)+paths(B,end)
    paths(A,end)=paths(C,end)+paths(D,end)
    paths(B,end)=paths(C,end)+paths(E,end)

    递归:

    每当走到一个位置时就会有两个或一个选择

    实现代码:

    int countPaths(boolean[][]grid,introw,intcol){
    if(!validSquare(grid,row,col)) return 0;
    if(isAtEnd(grid,row,col))return 1;
    return countPaths(grid,row+1,col)+countPaths(grid,row,col+1)
    }

    时间复杂度: O(2^n)

    递推:

    从后(end)推前方有几种方式走

    例:

    ​ 最下面一行到终点路线只有一条,所以最底下都是一,最后面的列也到终点也只有一条路线,所以都是一,以此类推得到每一个方块到终点的路径数如下图所示:

    opt--状态最佳路径数
    opt[i,j]--[i,j]位置状态最佳路径数
    opt[i-1,j]--[i-1,j]位置([i,j]位置下方)状态最佳路径数
    opt[i1,j-1]--[i,j-1]位置([i,j]位置右方)状态最佳路径数

    实现代码:

    for i in range(10, 0, -1):{
    for j in range(10, 0, -1):{
    if a[i,j] = '空地':
    opt[i,j] = opt[i-1,j] + opt[i, j-1]
    else://石头
    opt[i, j] =0
    }
    }

    时间复杂度: O(n)

  • 内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: