DFS 算法:记忆化搜索

在这里插入图片描述

我的个人主页 {\large \mathsf{{\color{Red} 我的个人主页} } } 我的个人主页

往 {\color{Red} {\Huge 往} } 期 {\color{Green} {\Huge 期} } 文 {\color{Blue} {\Huge 文} } 章 {\color{Orange} {\Huge 章}}


此系列更新频繁,求各位读者点赞
关注我可以了解更多内容哦
偷偷告诉你,我正在冲 1100 粉 {\color{Gray} {\small 偷偷告诉你,我正在冲1100粉} } 偷偷告诉你,我正在冲1100
你们有什么想了解的可以发在评论区,我会仔细的看 {\color{Gray} {\small 你们有什么想了解的可以发在评论区,我会仔细的看} } 你们有什么想了解的可以发在评论区,我会仔细的看
1100 粉时我会抓几个做文章 {\color{Gray} {\small1100粉时我会抓几个做文章} } 1100粉时我会抓几个做文章


今天我们学什么

今天我们要学习的是——记忆化搜索!
这是一种以空间换时间的算法,能有效提高效率
我们将会以一道“简单”的题入手,带你了解这个“有趣”的算法

例题

那么例题就是——斐波那契数列!
题目如下

斐波那契数列

题目描述

有一种兔子,出生后一个月就可以长大,然后再过一个月一对长大的兔子就可以生育一对小兔子且以后每个月都能生育一对。
现在,我们有一对刚出生的这种兔子,那么,第n个月时,我们会有多少对兔子呢?
假设所有的兔子都不会死亡。

题目输入

输入仅一行,包含一个自然数n。 n<=46

题目输出

输出仅一行,包含一个自然数,即第n个月时兔子的对数。

样例

样例 1
输入
5
输出
5

递推做法

我知道你想怎么做,这样呗

#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll f[50];
int main() {
	int n;
	cin >> n;
	f[1] = f[2] = 1;  // 初始化
	for (int i = 3; i <= n; i++) {
		f[i] = f[i - 1] + f[i - 2];
	}
	cout << f[n];
	return 0;
}

没错,这种代码效率高,是做这道题的不二之选
但是,我们想要递归的代码

递归

此时,作为OIer / coder的你 打出了GG 打出来了一下的代码

#include <bits/stdc++.h>
#define ll long long
using namespace std;

ll f(int x) {
	if (x == 1 || x == 2) {
		return 1;    // 若 x 为 1 或者 2 ,则返回 1
	}
	return f(x - 1) + f(x - 2);
}
int main() {
	int n;
	cin >> n;
	cout << f(n);
	return 0;
}

此时你看到了满屏的
在这里插入图片描述
这是为什么呢?
我们来画一颗搜索树(以5为例)
请添加图片描述

此时,我们可以发现
有些地方重复了!
请添加图片描述
我们此时为了快,要努力去把重复部分的计算次数变成1次而不是多次
我们可以在此处添加一个ans数组来记忆状况,这就是记忆化搜索,具体如下(需要自行理解):

#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll ans[50];
ll f(int x) {
	if (x == 1 || x == 2) {
		return 1;     // 若 x 为 1 或者 2 ,则返回 1
	}
	if (ans[x]) {
		return ans[x];   // 若 ans[x] 已经计算,则直接返回 ans[x]
	}

	return ans[x] = f(x - 1) + f(x - 2);  
	/*
	上面的一行代码使用了简写,也可以写作如下代码
	
	ans[x] = f(x - 1) + f(x - 2);
	return ans[x];
	
	上面的更加简洁,下面的更加容易理解
	*/
}
int main() {
	int n;
	cin >> n;
	cout << f(n);
	return 0;
}

怎么样,记忆化搜索是不是很简单呢?

总结

以下内容使用了AI大模型

记忆化搜索是一种以空间换时间的算法,用于优化递归中的重复计算。通过建立一个记忆数组,将已经计算过的结果保存起来,下次需要计算时直接查询数组,避免重复计算。记忆化搜索可以有效提高算法的效率,特别适用于递归问题。

在记忆化搜索中,需要注意以下几点:
- 在递归函数中添加记忆数组,用于保存已经计算过的结果;
- 在递归函数中,先查看记忆数组中是否已经有计算好的结果,若有则直接返回,若无则进行计算;
- 在计算完成后,将结果保存到记忆数组中;
- 主函数中调用递归函数,并输出结果。

记忆化搜索的实现步骤如下:
1. 创建记忆数组,大小与递归函数的参数范围相对应;
2. 在递归函数中,先检查记忆数组是否有计算好的结果,若有则直接返回结果;
3. 若记忆数组中没有计算好的结果,则进行计算,并将结果保存到记忆数组中;
4. 在主函数中调用递归函数,并输出结果。

记忆化搜索的优点是能够避免重复计算,提高算法效率。缺点是需要额外的空间来保存计算结果。

记忆化搜索在解决递归问题时非常有用,可以大大提高算法的效率。在实际应用中,可以根据问题的特点和递归深度来决定是否使用记忆化搜索。

再见!记得关注我哦

  • 22
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值