如果递归式严格符合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;
}