斐波那契系列问题的递归与动态规划

如果递归式严格符合F(n) = a*F(n - 1) + b*F(n-2)…k*F(n-i),那么它就是一个i阶递推式,必然可以用与i*i有关的状态矩阵的乘法表达

#include <iostream>
#include <vector>
using namespace std;
//返回斐波那契数列第N项
//递归(糟糕的解法)时间复杂度2^N
int f1(int n)
{
    if(n < 1)
        return 0;
    if(n == 1 || n == 2)
        return 1;
    return f1(n - 1) + f1(n - 2);
}
//DP解法,时间复杂度N
int f2(int n)
{
    if(n < 1)
        return 0;
    if(n == 1 || n == 2)
        return 1;
    int res = 1;
    int pre = 1;
    int temp  = 0;
    for(int i = 3; i <= n; ++i)
    {
        temp = res;
        res  = pre + res;
        pre  = temp;
    }
    return res;
}
//logN解法,数学推论较难
//怎么求一个矩阵的N次方,时间复杂度logN
vector<vector<int> > muliMatrix(vector<vector<int> >& m1, vector<vector<int> > &m2)
{
    vector<vector<int> > res(m1.size(), vector<int>(m2[0].size()));

    for(int i = 0; i < m1.size(); ++i)
        for(int j = 0; j < m2[0].size(); ++j)
        {
            for(int k = 0; k < m2.size(); ++k)
            {
                res[i][j] += m1[i][k] * m2[k][j];
            }
        }

    return res;
}
vector<vector<int> > matrixPower(vector<vector<int> > & m, int p)
{
     vector<vector<int> > res(m.size(), vector<int>(m.size(), 0));
     vector<int> temp;
    for(int i = 0; i < m.size(); ++i)
        res[i][i] = 1;

    vector<vector<int> > tmp(m.begin(), m.end());
    for(; p != 0; p >>= 1)
    {
        if(p & 1)
            res = muliMatrix(res, tmp);
        tmp = muliMatrix(tmp, tmp);
//         for(int i = 0; i < tmp.size(); ++i)
//    {
//        for(int j = 0; j < tmp[0].size(); ++j)
//            cout << tmp[i][j] << " ";
//        cout  << endl;
//    }
//    cout << "ttttttttttttt" << endl;
    }
    return res;
}
//用矩阵求斐波那契数列
int f3(int n)
{
    if(n < 1)
        return 0;
    if(n == 1 || n == 2)
        return 1;
    vector<vector<int> > base;
    vector<int> temp;
    temp.push_back(1);
    temp.push_back(1);
    base.push_back(temp);
    temp[1] = 0;
    base.push_back(temp);
    base = matrixPower(base, n - 2);
//    for(int i = 0; i < base.size(); ++i)
//    {
//        for(int j = 0; j < base[0].size(); ++j)
//            cout << base[i][j] << " ";
//        cout  << endl;
//    }
    return base[0][0] + base[1][0];
}
//青蛙跳台阶问题,一次可以跳1或2个台阶,问一个N级台阶有多少种跳法
//时间复杂度为N^2解法
int s1(int n)
{
    if(n < 1)
        return 0;
    if(n == 1 || n == 2)
        return n;
    return s1(n - 1) + s1(n - 2);
}
//Dp解法,时间复杂度N
int s2(int n)
{
     if(n < 1)
        return 0;
    if(n == 1 || n == 2)
        return n;
    int res = 2;
    int pre = 1;
    int temp = 0;
    for(int i = 3; i <= n; ++i)
    {
        temp = res;
        res = res + pre;
        pre = temp;
    }
    return res;
}
//矩阵解法,时间为logN
int s3(int n)
{
     if(n < 1)
        return 0;
    if(n == 1 || n == 2)
        return n;

    vector<vector<int> > base;
    vector<int> temp;
    temp.push_back(1);
    temp.push_back(1);
    base.push_back(temp);
    temp[1] = 0;
    base.push_back(temp);
    base = matrixPower(base, n - 2);
    return 2 * base[0][0] + base[1][0];
}
//母牛生小牛问题
int c1(int n)
{
    if(n < 1)
        return 0;
    if(n == 1 || n == 2 || n == 3)
        return n;
    return c1(n - 1) + c1(n - 3);
}
int c2(int n)
{
   if(n < 1)
        return 0;
    if(n == 1 || n == 2 || n == 3)
        return n;
    int res = 3;
    int pre = 2;
    int prePre = 1;
    int temp1 = 0;
    int temp2 = 0;
    for(int i = 4; i <= n; ++i)
    {
        temp1 = res;
        temp2 = pre;
        res = res + prePre;
        pre = temp1;
        prePre = temp2;
    }
    return res;
}
int c3(int n)
{
     if(n < 1)
        return 0;
    if(n == 1 || n == 2 || n == 3)
        return n;

    vector<vector<int> > base;
    vector<int> temp;
    temp.push_back(1);
    temp.push_back(1);
    temp.push_back(0);
    base.push_back(temp);
    temp[0] = 0;
    temp[1] = 0;
    temp[2] = 1;
    base.push_back(temp);
    temp[0] = 1;
    temp[1] = 0;
    temp[2] = 0;
    base.push_back(temp);
    base = matrixPower(base, n - 3);
    return 3 * base[0][0] + 2 * base[1][0] + base[2][0];
}

int main()
{
    cout << f1(10) << endl;
    cout << f2(10) << endl;
    cout << f3(10) << endl;
    cout << "==========" << endl;
     cout << c1(10) << endl;
    cout << c2(10) << endl;
    cout << c3(10) << endl;
    cout << "==========" << endl;
     cout << s1(10) << endl;
    cout << s2(10) << endl;
    cout << s3(10) << endl;
    cout << "==========" << endl;
}

猜你喜欢

转载自blog.csdn.net/wzc2608/article/details/80889493
今日推荐