斐波那契数列

来源:互联网 发布:传承家谱软件 编辑:程序博客网 时间:2024/06/07 01:38
/************************************ *description:求斐波那契数列的第n项 *            f(n)=f(n-1)+f(n-2) ***********************************/#include <iostream>#include <vector>using namespace std;//方法一:递归//时间复杂度:O(2^n)int Fibonacci_1(int n){    if (n < 1)        return 0;    if (n == 1 || n == 2)        return 1;    return Fibonacci_1(n - 1) + Fibonacci_1(n - 2);}//方法二:轮询。从前往后,一直求到第n项。//时间复杂度:O(n)int Fibonacci_2(int n){    if (n < 1)        return 0;    if (n == 1 || n == 2)        return 1;    int res;    int pre_1 = 1, pre_2 = 1;    for (int i = 3; i <= n; i++)    {        res = pre_1 + pre_2;        pre_2 = pre_1;        pre_1 = res;    }    return res;}//方法二:状态矩阵。//      对于严格遵循f(n)=f(n-1)+f(n-2)的数列,一定满足[f(n),f(n-1)]=[f(n-1),f(n-2)]A。//      其中A是一个2*2的状态矩阵。把f(1)=1,f(2)=1,f(3)=2,f(4)=3带入上式可求得A。//      [f(3),f(2)]=[f(2),f(1)]A=[1,1]A;[f(4),f(3)]=[f(3),f(2)]A==[1,1]A^2...//      [f(n),f(n-1)]=[f(n-1),f(n-2)]A=[1,1]A^(n-2),问题转化为求A的(n-2)次方的问题。//      以整数为例,求10的75次方。75的二进制表示为1001011,10^75=10^64*10^8*10^2*10^1//      先求10^1,再求10^2,再求10^4、10^8...10^64,把二进制位1对应的部分累积相乘即可。//时间复杂度:O(logn)vector<vector<int>> matrixMulti(const vector<vector<int>> &A, const vector<vector<int>> &B){    vector<vector<int>> tmp(A.size(), vector<int>(B[0].size(), 0));    for (int i = 0; i < A.size(); i++)    {        for (int j = 0; j < B[0].size(); j++)        {            for (int k = 0; k < A[0].size(); k++)            {                tmp[i][j] += A[i][k] * B[k][j];            }        }    }    return tmp;}vector<vector<int>> matrixPower(const vector<vector<int>> &A, int n){    vector<vector<int>> res(A.size(), vector<int>(A[0].size(), 0));    for (int i = 0; i < A.size(); i++)        res[i][i] = 1;    vector<vector<int>> tmp = A;    for (; n != 0 ;n >>= 1)    {        if (n & 1)            res = matrixMulti(res, tmp);        tmp = matrixMulti(tmp, tmp);    }    return res;}int Fibonacci_3(int n){    vector<vector<int>> A(2, vector<int>(2, 0));    A[0][0] = 1;    A[0][1] = 1;    A[1][0] = 1;    A[1][1] = 0;    A = matrixPower(A, n - 2);    vector<vector<int>> res(1, vector<int>(2, 1));    res = matrixMulti(res, A);    return res[0][0];}int main_01(){    cout << Fibonacci_3(6) << endl;    return 0;}//补充问题1:爬台阶问题,每次可以爬1阶或者2阶,求n级台阶的爬法。初值f(1)=1,f(2)=2的斐波那契数列问题。//补充问题2:生小牛问题,成熟母牛每年生一只小牛,且永远不死。第一年有1头成熟母牛,//         第二年开始生一头小牛,小牛三年后成熟开始生小牛,求n年后牛的总数。//         n-1年的牛都会活到n年,且(n-3)年的牛在第n年都成熟生一只小牛。//         所以,f(n)=f(n-1)+f(n-3),和斐波那契数列的问题类似。//         用状态矩阵求取时[f(n),f(n-1),f(n-2)]=[3,2,1]A^(n-3),A的尺寸:3*3




                                             
0 0
原创粉丝点击