• 【编程题目】题目:定义 Fibonacci 数列 输入 n,用最快的方法求该数列的第 n 项。


    第 19 题(数组、递归):
    题目:定义 Fibonacci 数列如下:
    / 0 n=0
    f(n)= 1 n=1
    / f(n-1)+f(n-2) n=2
    输入 n,用最快的方法求该数列的第 n 项。

    思路:递归和非递归的 下面的代码有个问题,没有考虑大数越界。返回值应该设成long long型的

    递归速度非常慢

    /*
    第 19 题(数组、递归):
    题目:定义 Fibonacci 数列如下:
    / 0 n=0
    f(n)= 1 n=1
    / f(n-1)+f(n-2) n=2
    输入 n,用最快的方法求该数列的第 n 项。
    start time 13:05
    end time 13:16
    */
    
    #include <stdio.h>
    
    //递归
    int Fibonacci(int n)
    {
        switch(n)
        {
        case 0:
            return 0;
        case 1:
            return 1;
        default:
            return Fibonacci(n - 1) + Fibonacci(n - 2);
        }
    }
    
    //非递归
    int nonrecursionFibonacci(int n)
    {
        int a = 0, b = 1;
        switch(n)
        {
        case 0:
            return 0;
        case 1:
            return 1;
        default:
            {
                for (int i = 0; i < n - 1; i++)
                {
                    int c = a + b;
                    a = b;
                    b = c;
                }
                return b;
            }
        }
    }
    
    int main()
    {
        //int f = Fibonacci(10000);
        int ff = nonrecursionFibonacci(10000);
        return 0;
    }

    网上有O(logN)的解法

    http://leowzy.iteye.com/blog/787947

    这还不是最快的方法。下面介绍一种时间复杂度是O(logn)的方法。在介绍这种方法之前,先介绍一个数学公式:
    {f(n), f(n-1), f(n-1), f(n-2)} ={1, 1, 1,0}n-1
    (注:{f(n+1), f(n), f(n), f(n-1)}表示一个矩阵。在矩阵中第一行第一列是f(n+1),第一行第二列是f(n),第二行第一列是f(n),第二行第二列是f(n-1)。)
    有了这个公式,要求得f(n),我们只需要求得矩阵{1, 1, 1,0}的n-1次方,因为矩阵{1, 1, 1,0}的n-1次方的结果的第一行第一列就是f(n)。这个数学公式用数学归纳法不难证明。感兴趣的朋友不妨自己证明一下。
    现在的问题转换为求矩阵{1, 1, 1, 0}的乘方。如果简单第从0开始循环,n次方将需要n次运算,并不比前面的方法要快。但我们可以考虑乘方的如下性质:
             /   an/2*an/2                       n为偶数时
    an=
                a(n-1)/2*a(n-1)/2             n为奇数时
    要求得n次方,我们先求得n/2次方,再把n/2的结果平方一下。如果把求n次方的问题看成一个大问题,把求n/2看成一个较小的问题。这种把大问题分解成一个或多个小问题的思路我们称之为分治法。这样求n次方就只需要logn次运算了。
    实现这种方式时,首先需要定义一个2×2的矩阵,并且定义好矩阵的乘法以及乘方运算。当这些运算定义好了之后,剩下的事情就变得非常简单。完整的实现代码如下所示。

    #include <cassert>
    ///////////////////////////////////////////////////////////////////////
    // A 2 by 2 matrix
    ///////////////////////////////////////////////////////////////////////
    struct Matrix2By2
    {
           Matrix2By2
           (
                long long m00 = 0, 
                long long m01 = 0, 
                long long m10 = 0, 
                long long m11 = 0
           )
           :m_00(m00), m_01(m01), m_10(m10), m_11(m11) 
           {
           }
    
          long long m_00;
          long long m_01;
          long long m_10;
          long long m_11;
    };
    
    ///////////////////////////////////////////////////////////////////////
    // Multiply two matrices
    // Input: matrix1 - the first matrix
    //         matrix2 - the second matrix
    //Output: the production of two matrices
    ///////////////////////////////////////////////////////////////////////
    Matrix2By2 MatrixMultiply
    (
          const Matrix2By2& matrix1, 
          const Matrix2By2& matrix2
    )
    {
          return Matrix2By2(
                 matrix1.m_00 * matrix2.m_00 + matrix1.m_01 * matrix2.m_10,
                 matrix1.m_00 * matrix2.m_01 + matrix1.m_01 * matrix2.m_11,
                 matrix1.m_10 * matrix2.m_00 + matrix1.m_11 * matrix2.m_10,
                 matrix1.m_10 * matrix2.m_01 + matrix1.m_11 * matrix2.m_11);
    }
    
    ///////////////////////////////////////////////////////////////////////
    // The nth power of matrix 
    // 1   1
    // 1   0
    ///////////////////////////////////////////////////////////////////////
    Matrix2By2 MatrixPower(unsigned int n)
    {
           assert(n > 0);
    
           Matrix2By2 matrix;
          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;
    }
    
    ///////////////////////////////////////////////////////////////////////
    // Calculate the nth item of Fibonacci Series using devide and conquer
    ///////////////////////////////////////////////////////////////////////
    long long Fibonacci_Solution3(unsigned int n)
    {
          int result[2] = {0, 1};
          if(n < 2)
                return result[n];
    
           Matrix2By2 PowerNMinus2 = MatrixPower(n - 1);
          return PowerNMinus2.m_00;
    }
  • 相关阅读:
    利用clear清除浮动的一些问题
    配置SpringBoot方便的切换jar和war
    java并发实战:连接池实现
    canvas绘制圆角头像
    对象的合并及拷贝
    JS数组去重
    浏览器端用JS实现创建和下载图片
    超过固定宽度(或行数)显示...(或省略)
    ssh实现免密登录
    Mac 日常使用问题收集
  • 原文地址:https://www.cnblogs.com/dplearning/p/3972643.html
Copyright © 2020-2023  润新知