当前位置:   article > 正文

【递归 & 动态规划 & 备忘录法】Fibonacci数列(斐波那契数列)(C++)_斐波那契数列c++递归

斐波那契数列c++递归

一、什么是Fibonacci数列

  • 斐波那契数列指的是这样一个数列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144…
  • 用文字来说,就是从第3项开始,每一项都等于前两项之和。
  • 至于包不包括0,一番查阅后没有得到证实… 不过重要的是“第3项开始,每一项都等于前两项之和”这个定义。

二、简单递归

1. 设计递归方程

  • 斐波那契数列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144…
  • 递归定义
    F ( n ) = { 1 n = 1 1 n = 2 F ( n − 1 ) + F ( n − 2 ) n > 2 F(n)=
    {1n=11n=2F(n1)+F(n2)n>2
    F(n)=11F(n1)+F(n2)n=1n=2n>2
  • 当 n=1 || n=2 时,结束递归。

2. 编写程序代码

// 【递归】Fibonacci数列(斐波那契数列)
#include<iostream>
using namespace std;

int fibonacci(int num);

int main()
{
	int num = 0; // 项数

	cout << "Fibonacci数列,请输入项数(正整数):";
	cin >> num;

	cout << "此项为:" << fibonacci(num) << endl;	//输出结果

	return 0;
}

int fibonacci(int num)
{
	if (num <= 2)
		return 1;		// F(1)=1,F(2)=1
	else
		return fibonacci(num - 1) + fibonacci(num - 2);	// F(n)=F(n-1)+F(n-2)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

3. 运行结果

运行截图

三、动态规划

1. 再次分析上述递归算法

  • 我们举例研究一下上面的递归算法:计算F(5)
    F(5) = F(4) + F(3);
    -> F(4) = F(3) + F(2);
       -> F(3) = F(2) + F(1);
          -> F(2) = 1;
          -> F(1) = 1;
    -> F(3) = F(2) + F(1); // 重复计算了 F(3)
       -> F(2) = 1;
       -> F(1) = 1;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 从F(5)的例子中可以明显看到在递归中F(3)被我们重复计算了;
    少次循环中这并不明显,但可以想象,当递归层数非常大时,我们将会进行非常大量的重复计算,浪费大量的时间和资源。
  • 我们很容易想到:既然重复计算了,那我们把计算过的值保存一下就好了嘛。

2. 动态规划

  • 动态规划的基本思想是:将原问题拆分为若干子问题,自底向上的求解。
  • 自底向上的求解,即是先计算子问题的解,再得出原问题的解。动态规划详情–>详情

3. 备忘录法

  • 备忘录法是自顶向下的算法,控制结构与直接递归相似,但其维护了一个记录子问题的表,以此避免了子问题的重复求解。

4. 程序实现

(1)动态规划 - 自底向上
// 【动态规划】Fibonacci数列(斐波那契数列)
#include<iostream>
using namespace std;

int main()
{
	// 项数
	int n;
	cout << "Fibonacci数列,请输入项数:";
	cin >> n;

	// 保存计算过的值
	int* F = new int[n];
	F[1] = 1; // F(1)=1
	F[2] = 1; // F(2)=1

	// 自底向上计算
	for (int i = 3;i < n;i++)
		F[i] = F[i - 1] + F[i - 2];

	// 输出结果
	cout << F[n] << endl;
	
	delete[] F;

	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
(2)备忘录法 - 自顶向下
// 【备忘录法】Fibonacci数列(斐波那契数列)
#include<iostream>
using namespace std;

int F[256] = { 0 };	// 保存子问题解的表

int fibonacci(int n);

int main()
{
	// 项数
	int n;
	cout << "Fibonacci数列,请输入项数(正整数):";
	cin >> n;

	// 保存子问题解的表,前两个数为 1
	F[1] = 1;
	F[2] = 1;

	// 自顶向下计算,并保存子问题的解;输出结果
	cout << fibonacci(n) << endl;

	return 0;
}

int fibonacci(int n)
{
	if (F[n] > 0)
		return F[n];
	else
		return (F[n] = fibonacci(n - 1) + fibonacci(n - 2));
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 运行结果都一样,如上图。

三、友情链接~


最后,非常欢迎大家来讨论指正哦!

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

闽ICP备14008679号