您的位置:首页 > 编程语言 > C语言/C++

Fibonacci数列(斐波那契数列) 递归&动态规划(C++)

2020-06-01 05:12 1326 查看

文章目录

  • 三、动态规划
  • 一、什么是Fibonacci数列

    斐波那契数列指的是这样一个数列:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144…
    用文字来说,就是斐波那契数列由0和1开始,之后的斐波那契数就是由之前的两数相加而得出。

    二、简单递归

    1. 设计递归方程

    • 斐波那契数列:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144…
    • 递归定义:
      F(n)={1n=11n=2F(n−1)+F(n−2)n>2 F(n)=\begin{cases} 1 & n=1 \\ 1 & n=2 \\ F(n-1)+F(n-2) & n>2 \end{cases} F(n)=⎩⎪⎨⎪⎧​11F(n−1)+F(n−2)​n=1n=2n>2​

    2. 确定边界条件

    明显可以看出数列前两项为1,第三项开始,每项为前两项的和;故当 n=0 || n=1 时应跳出。

    3. 编写程序代码

    // 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 == 0)
    return 0;		// F(0)=0
    else if (num == 1)
    return 1;		// F(1)=1
    else
    return fibonacci(num - 1) + fibonacci(num - 2);	// F(n)=F(n-1)+F(n-2)
    }

    4. 运行结果展示

    三、动态规划

    1. 原理/思想

    • 我们举例研究一下上面的递归算法:计算F(4)
    F(4) = F(3) + F(2);
    F(3) = F(2) + F(1); // 重复计算了 F(2)
    F(2) = F(1) + F(0); // 重复计算了 F(1)
    F(1) = 1;
    F(0) = 0;
    • 从F(4)的例子中可以明显看到在递归中F(2)和F(1)F(0)被我们重复计算了;
      少次循环中这并不明显,但可以想象,当递归层数非常大时,我们将会进行非常大量的重复计算

    • 即使没有学习过动态规划,我想也很容易想到:既然重复计算了,那我们把计算过的值保存一下就好了。

    2. 程序实现

    (1)使用数组保存

    // Fibonacci数列(斐波那契数列) 使用数组的动态规划
    #include<iostream>
    using namespace std;
    
    int fibonacci(int arr[], int num);
    
    int main()
    {
    int num; // 项数
    cout << "Fibonacci数列,请输入项数:";
    cin >> num;
    
    int* arr = new int[num]; // 保存计算过的值
    arr[0] = 0; // F(0)=0
    arr[1] = 1; // F(1)=1
    
    cout << "此项为:" << fibonacci(arr, num) << endl;	//输出结果
    
    delete[] arr;
    
    return 0;
    }
    
    int fibonacci(int arr[], int num)
    {
    if (num < 2)	// 前两项已经保存
    return arr[num];
    else
    return (arr[num] = fibonacci(arr, num - 1) + fibonacci(arr, num - 2)); // 保存并返回值
    }

    (2)再简单一点!

    • 使用数组,我们首先需要创建一个数组,然后以此存入每一项的值
    • 而此时,我们已经可以明显感受到:其实我们只需要知道前两项的值就可以了!
    • 因此!我们可以再改进一下下:
    // Fibonacci数列(斐波那契数列) 动态规划
    #include<iostream>
    
    using namespace std;
    
    int fibonacci(int n);
    
    int main()
    {
    while (true) {
    
    int num; // 项数
    cout << "Fibonacci数列,请输入项数:";
    cin >> num;
    
    cout << "此项为:" << fibonacci(num) << endl;	//输出结果
    }
    
    return 0;
    }
    
    int fibonacci(int n) {
    
    if (n == 0)
    return 0;
    
    int p1 = 0;		// 第零项的值
    int p2 = 1;		// 第一项的值
    
    for (int i = 2; i <= n; i++)
    {
    int temp = p1 + p2;
    p1 = p2;
    p2 = temp;
    }
    return p2;
    }
    • 运行结果都一样,就不上图了~

    *其它一些常见算法请参阅此链接~

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

    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: