当前位置:   article > 正文

dfs + 记忆化搜索_dfs加上记忆化

dfs加上记忆化

上篇文章给大家带来了dfs的走迷宫,那么今天的文章继续拓展dfs的相关知识。

咱们在做题的时候往往会遇到类似数塔这种题,给个n层数塔:

                 7

           3          8

      3         4          6  

7         4          7           8

              .......... 

请你从第一层开始以一种走法走到最后一层使路过的数加和最大?

在分析这道题的时候,我们可以用动态规划的方法来解决,设置二维dp[i][j]数组含义为第i层第j列的总和最小经历值,所以其状态方程为dp[i][j] = max(dp[i + 1][j],dp[i + 1][j + 1]) + a[i][j]

所以遍历顺序+初始化:

  1. for(int j = 0;j <= n;j++)
  2. {
  3. dp[n][j] = a[n][j];//将最后一层赋值初始化
  4. }
  5. for(int i = n - 1;i >= 1;i--)//由n - 1层到第一层递推
  6. {
  7. for(int j = 1;j <= i;j++)
  8. {
  9. dp[i][j] = max(dp[i + 1][j],dp[i + 1][j + 1]) + a[i][j];
  10. }
  11. }

其实根据动态规划的分析思路,我们不难发现这题跟咱们的dfs走迷宫也是有些相似的。在分析这道题之前,咱们先用dfs的思路来分析这道题,首先判断递归的方向,咱们在走迷宫是通过枚举横纵坐标来判断走的方向,这道题咱们可以定义一个二维塔数组存储数,通过dfs(i,j)分别代表维数组两个参数来控制方向.....

  1. int dfs(int i,int j)
  2. {
  3. if(i == n) return a[i][j];//递归到最后一层返回
  4. return dp[i][j] = max(dfs(i + 1,j),dfs(i + 1,j + 1)) + a[i][j];
  5. }

But,这种暴力搜索我们会搜索所有的可能情况,会有很多中间值被重复计算,所以咱们这里会用到记忆化搜索,通过存储每一位置的最小值来达到避免重复运算,代码如下....

  1. int dfs(int i,int j)
  2. {
  3. if(i == n) return a[i][j];
  4. if(dp[i][j] > 0) return dp[i][j];//记忆
  5. return dp[i][j] = max(dfs(i + 1,j),dfs(i + 1,j + 1)) + a[i][j];
  6. }

这样就会将复杂度优化到O(n次方)次计算。记忆化搜索的目的是跳过已经算过的重复值来减小递归的次数

好了,今天的分享到这里了,别忘记三连支持,感谢收看!!!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/463688
推荐阅读
相关标签
  

闽ICP备14008679号