• 斐波那契数列 --- 四层优化


    斐波那契数列

    起源

    兔子问题:“假定一对大兔子每月能生一对小兔子,且每对新生的小兔子经过一个月可以长成一对大兔子,具备繁殖能力,如果不发生死亡,且每次均生下一雌一雄,问一年后共有多少对兔子?”

    分析:第一个月兔子没有繁殖能力,所以还是一对;两个月后生下一对兔子,共有两对;三个月后,老兔子生下一对,小兔子还没有繁殖能力,所以一共是三对,以此类推,可以列出下表

    表中1,1,2,3,5,8,13.....构成一个序列,这个数列有一个特点就是前两项之和等于后一项

    数学函数定义:


    方法1(递归)

    时间复杂度:O(N2),空间复杂度:O(N)

    long long Fibonacci(unsigned int n)
    {
        return n < 2 ? n : Fibonacci(n - 1) + Fibonacci(n - 2);
    }

     

    方法2(循环)

    时间复杂度:O(N),时间复杂度:O(1)

    long long Fibonacci(unsigned int n)
    {
        int result[2] = { 0, 1 };
        if (n < 2)
            return result[n];
    
        long long fibNOne = 1, fibNTwo = 0, fibN = 0;
        for (int i = 1; i < n; i++)
        {
            fibN = fibNOne + fibNTwo;
            fibNTwo = fibNOne;
            fibNOne = fibN;
        }
        return fibN;
    }

     

    方法3(通项公式)

    时间复杂度:O(logn),空间复杂度:O(1)

    long long Fibonacci(unsigned int n)
    {
        return (pow((1 + sqrt(5)) / 2, n) - pow((1 - sqrt(5)) / 2, n)) / sqrt(5);
    }

     

    方法4(矩阵乘法实现,最优解)

    时间复杂度:O(logn),空间复杂度:O(1)

    #include<iostream>
    #include<string>
    using namespace std;
    
    //定义2×2矩阵;
    struct Matrix2by2
    {
        //构造函数
        Matrix2by2
        (
            long m_00,
            long m_01,
            long m_10,
            long m_11
        )
            :m00(m_00), m01(m_01), m10(m_10), m11(m_11)
        {
        }
    
        //数据成员
        long m00;
        long m01;
        long m10;
        long m11;
    };
    
    //定义2×2矩阵的乘法运算
    Matrix2by2 MatrixMultiply(const Matrix2by2& matrix1, const Matrix2by2& matrix2)
    {
        Matrix2by2 matrix12(1, 1, 1, 0);
        matrix12.m00 = matrix1.m00 * matrix2.m00 + matrix1.m01 * matrix2.m10;
        matrix12.m01 = matrix1.m00 * matrix2.m01 + matrix1.m01 * matrix2.m11;
        matrix12.m10 = matrix1.m10 * matrix2.m00 + matrix1.m11 * matrix2.m10;
        matrix12.m11 = matrix1.m10 * matrix2.m01 + matrix1.m11 * matrix2.m11;
        return matrix12;
    
    }
    
    
    //定义2×2矩阵的幂运算
    Matrix2by2 MatrixPower(unsigned int n)
    {
        Matrix2by2 matrix(1, 1, 1, 0);
        if (n == 1)
        {
            matrix = Matrix2by2(1, 1, 1, 0);
        }
        else if (n % 2 == 0)
        {
            matrix = MatrixPower(n / 2);
            matrix = MatrixMultiply(matrix, matrix);
        }
        else if (n % 2 == 1)
        {
            matrix = MatrixPower((n - 1) / 2);
            matrix = MatrixMultiply(matrix, matrix);
            matrix = MatrixMultiply(matrix, Matrix2by2(1, 1, 1, 0));
        }
        return matrix;
    }
    //计算Fibnacci的第n项
    long Fibonacci(unsigned int n)
    {
        if (n == 0)
            return 0;
        if (n == 1)
            return 1;
    
        Matrix2by2 fibMatrix = MatrixPower(n - 1);
        return fibMatrix.m00;
    
    }
    
    int main()
    {
        cout << "Enter A Number:" << endl;
        unsigned int number;
        cin >> number;
        cout << Fibonacci(number) << endl;
        return 0;
    }

    斐波那契数列的应用题:

    1 青蛙跳台阶问题

    一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个n级的台阶总共有多少种跳法。

    提示:f(n) = f(n-1) + f(n-2)

    扩展题:

    一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶......也可以跳上n级台阶。求该青蛙跳上一个n级的台阶总共有多少种跳法。

    提示:f(n) = 2n-1

    2 如果我们用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问8个2*1的小矩形无重叠地覆盖一个2*8的大矩形,总共有多少种方法?

    提示:f(8) = f(7) + f(6)

    参考:

    https://blog.csdn.net/qq_41035588/article/details/81814547

  • 相关阅读:
    GitLab 介绍
    git 标签
    git 分支
    git 仓库 撤销提交 git reset and 查看本地历史操作 git reflog
    git 仓库 回退功能 git checkout
    python 并发编程 多进程 练习题
    git 命令 查看历史提交 git log
    git 命令 git diff 查看 Git 区域文件的具体改动
    POJ 2608
    POJ 2610
  • 原文地址:https://www.cnblogs.com/zkfopen/p/11245857.html
Copyright © 2020-2023  润新知