基本思想

记忆化搜索是深度优先搜索(DFS)中的一种剪枝方法,那什么是记忆化搜索呢?顾名思义,记忆化搜索就是让程序记住一些东西,然后可以在需要用的时候可以瞬间调用,不需要再进行一次复杂的计算!

怎么记?
 首先,记忆需要大脑来存储数据,什么来模拟大脑? 数组
 其次,记忆需要现有的知识用来记住,知识从哪里来? 以前求出的数据。
这样,我们如果要用到以前求过的数据,就可以从数组中调用,可以大大提高我们程序的运行速度

样例

斐波那契数列计算:斐波那契数列是这样的:1、1、2、3、5、8、13、21、34…… 发现规律了吗? 第一项和第二项是1,除了前面两个数外,每一个数都是前面两个数的和。 这样的题大家应该都做过,现在我们规定一下输入输出格式。

输入格式:

一个正整数N(1≤N≤90)表示输出斐波那契数列的前N项。

输出格式:

共 N 行,每行两个正整数 i、t,表示斐波那契数列第 i 项是 t。

普通的深度优先搜索(递归求解)
#include <bits/stdc++.h> 
using namespace std;
int n; 
long long fbnq(int n)
{
	if (n==1 || n==2)
		return 1;
	return fbnq(n-1)+fbnq(n-2);
}
int main()
{
	cin >>n;
	for (int i=1;i<=n;i++)
		cout <<i <<" " <<fbnq(i) <<endl;
	return 0;
}

运行一下,发现前面 40 项还好,到了后面,速度就突然下降,90项的话大概要2000000年! 那么,我们该怎么办? 我们可以对这个程序计算过的数进行观察(假设当前要计算的是 fbnq(7) ): 我们发现,这幅图中:

    7 被算了 1 次;

    6 被算了 1 次;

    5 被算了 2 次;

    4 被算了 3 次;

    3 被算了 5 次;

    2 被算了 8 次;

    1 被算了 5 次;

    这个增长率是非常可观的,除了最后一项,其他的数据正好是 斐波那契数列。

    我们知道 斐波那契数列 到达第47项,就可以超过 int 范围! 第93项就可以超过 long long 范围!

    这么大的数,怎么可能不超时?

    再想一想,同样的东西算了很多遍,为什么不用 “大脑” 将它们 记下来呢? 这样就不用重复计算,只需要直接调用就可以了!!!

    OK呀!
记忆化搜索 程序
#include <bits/stdc++.h> 
using namespace std;
long long n,a[100];    //数组a 为大脑,这里一点要用 long long,原因自己想
long long fbnq(int n)
{
	if (n==1 || n==2)        //前两项都是 1
		return 1;
	if (!a[n])              //如果记忆为空
		a[n]=fbnq(n-1)+fbnq(n-2);        //记住这个值
	return a[n];        //返回记忆中的值
}
int main()
{
	cin >>n;
	for (int i=1;i<=n;i++)
		cout <<i <<" " <<fbnq(i) <<endl;        //输出
	return 0;
}

这可能有人要问:为什么不直接用循环搞定呢,又方便又快捷?? 是的,一个循环确实方便许多,但这里主要讲的是方法,这个方法在面对 用深度优先搜索 解决 但是会超时 的题目时,可能用得上。