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]

所以遍历顺序+初始化:

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次方)次计算。记忆化搜索的目的是跳过已经算过的重复值来减小递归的次数

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

记得开心一点嘛

您的打赏是对我最大的鼓励与期待

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值