赞
踩
上篇文章给大家带来了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]。
所以遍历顺序+初始化:
- for(int j = 0;j <= n;j++)
- {
- dp[n][j] = a[n][j];//将最后一层赋值初始化
- }
- for(int i = n - 1;i >= 1;i--)//由n - 1层到第一层递推
- {
- for(int j = 1;j <= i;j++)
- {
- dp[i][j] = max(dp[i + 1][j],dp[i + 1][j + 1]) + a[i][j];
- }
- }
其实根据动态规划的分析思路,我们不难发现这题跟咱们的dfs走迷宫也是有些相似的。在分析这道题之前,咱们先用dfs的思路来分析这道题,首先判断递归的方向,咱们在走迷宫是通过枚举横纵坐标来判断走的方向,这道题咱们可以定义一个二维塔数组存储数,通过dfs(i,j)分别代表维数组两个参数来控制方向.....
- int dfs(int i,int j)
- {
- if(i == n) return a[i][j];//递归到最后一层返回
- return dp[i][j] = max(dfs(i + 1,j),dfs(i + 1,j + 1)) + a[i][j];
- }
But,这种暴力搜索我们会搜索所有的可能情况,会有很多中间值被重复计算,所以咱们这里会用到记忆化搜索,通过存储每一位置的最小值来达到避免重复运算,代码如下....
- int dfs(int i,int j)
- {
- if(i == n) return a[i][j];
- if(dp[i][j] > 0) return dp[i][j];//记忆
- return dp[i][j] = max(dfs(i + 1,j),dfs(i + 1,j + 1)) + a[i][j];
- }
这样就会将复杂度优化到O(n次方)次计算。记忆化搜索的目的是跳过已经算过的重复值来减小递归的次数。
好了,今天的分享到这里了,别忘记三连支持,感谢收看!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。