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


    斐波那契数列

    起源

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

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

    表中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

  • 相关阅读:
    2. Add Two Numbers
    8. String to Integer (atoi)
    18. 4Sum
    15. 3Sum
    1. Two Sum
    227. Basic Calculator
    7. Reverse Integer
    PostMessage和SendMessage的区别
    Date Time Picker控件
    git 设置和取消代理
  • 原文地址:https://www.cnblogs.com/zkfopen/p/11245857.html
Copyright © 2020-2023  润新知