二维空间的dp详解(自顶向下and自底向上)

例题:

准备了两道做法几乎相同的二维空间的dp题目

题目一:LeetCode-64最小路径和
Leetcode64
题目二:蓝桥杯-跳跃
跳跃

两者区别只在于子问题的个数,题目一的个数只有2个方向,而题目二有9个方向。

自顶向下的好处

  1. 有助于理解dfs、bfs等等算法。
  2. 相比自底向上来说,前期虽然痛苦,但是当你清楚结果体系,熟悉后,你会发现写dp递归法比递推法写的快得多。
  3. 容错性大,就是用递推方法的话,可能会被一些判断的小错误绊住脚,而递归方法只要base case不出差错,一般没有问题。

自顶向下的函数结构详解:

dp函数的结构(可结合代码画递归树理解)无非就是:

  • 递归树的叶子结点的跳出条件->对应base case(决定子问题的深度(个数))、base case一般为最简单的题解子状态
  • 递归函数的主体->对应状态转移方程(递归树的展开)。
  • 非叶子结点(子问题)的跳出条件->将return结果写在递归树展开的后面即可 总的过程:通过状态转移方程不断将递归树延伸,直到触及base case停止延伸,往前执行之前的递归,这样就完成了每个非叶子结点的结果跳出,最终得到题解。

但要是这样写的话很快就会超时,原因是:递归树上可能大量结点重复计算,这个时候就需要一个备忘录一样的东西将以及计算好的题解保存,可将备忘录添加到base case中来,实际上我说的base case决定递归树的深度不完全正确,准确来说应该是决定子树的深度,因为递归过程实际上是一个入栈和出栈的过程,所以首先计算的是最深的那颗树。

划重点:

递归的结构:

  1. base case (决定递归树深度,叶子结点的结果)
  2. 状态转移方程(决定递归树的延伸方式)
  3. 处理完子问题的返回(决定非叶子结点的处理结果)

递归的原理:

这方面也没办法讲的明白,递归实际上就是一个后进先出的栈的形式,即递归就是入栈和出栈的过程,根据递归树结合深搜理解是最好的。

题目一(强烈建议用递归法):

DP函数递归解决:

int dp(vector<vector<int>>& grid,vector<vector<int>>&memo,int x,int y){
   
      if(x<0||y<0) return 666;
      //base case:
      if(x==0&&y==0) return grid[x][y];
      if(memo[x][y]!=-1) return memo[x][y];
      
      //condition transfer:
      int a = min(dp(grid,memo,x-1,y),dp(grid,memo,x,y-1));
      //更新备忘录
        memo[
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值