问题描述:
定义一组叫做扩充的Fibonacci数如下,己知X与Y 两个数,于是扩充Fibonacci数 Fi 为:
Fi=⎧⎩⎨11X∗Fi−2+Y∗Fi−1i=1i=2i>2
因此,当X=Y=l 时,这一组扩充的Fibonacci 数就变成一般的Fibonacci 数了,现在请写一个函数,
接收一个n 值,不用数组与递归的方法算出下面的结果:
F0∗Fn+F1∗Fn−1+…+Fi∗Fn−i+…+Fn−1∗F1+FnF0
#include<iostream>
using namespace std;
/*
定义一组叫做扩充的Fibonacci数如下,己知X与Y 两个数,于是扩充Fibonacci数Fi为:
| 1, i=1
Fi=| 1, i=2
| X*Fi-2+ Y*Fi-1
因此,当X=Y=l 时,这一组扩充的Fibonacci 数就变成一般的Fibonacci 数了,
现在请写一个函数,接收一个n 值,不用数组与递归的方法算出下面的结果:
F0*Fn + F1*Fn-1 +…+ Fi*Fn-i +…+ Fn-1*F1 +FnF0
*/
class U4X4Matrix
{
public:
unsigned long A[4][4];
public:
//赋值构造函数
U4X4Matrix(unsigned long B[4][4]){
for (int i(0); i < 4; i++)
for (int j(0); j < 4; j++)
A[i][j] = B[i][j];
}
//赋值复制构造函数
U4X4Matrix(const U4X4Matrix &m){
for (int i(0); i < 4; i++)
for (int j(0); j < 4; j++)
A[i][j] = m.A[i][j];
}
//拷贝复制构造函数
U4X4Matrix operator = (const U4X4Matrix &m){
for (int i(0); i < 4; i++)
for (int j(0); j < 4; j++)
A[i][j] = m.A[i][j];
return *this;
}
//A * leftMatrix
void U4X4MatrixRightMul(U4X4Matrix leftMatrix){
U4X4Matrix temp = *this;
for (int i(0); i < 4;i++)
for (int j(0); j < 4; j++)
{
A[i][j] = temp.A[i][0] * leftMatrix.A[0][j] + temp.A[i][1] * leftMatrix.A[1][j] +
temp.A[i][2] * leftMatrix.A[2][j] + temp.A[i][3] * leftMatrix.A[3][j];
}
}
void U4X4Matrix_Power_N(int n){
if (n == 1) return;
if (n % 2 == 0){
U4X4Matrix_Power_N(n >> 1);
U4X4Matrix temp = *this;
U4X4MatrixRightMul(temp);
return;
}
U4X4Matrix temp1 = *this;
U4X4Matrix_Power_N(n >> 1);
U4X4Matrix temp2 = *this;
U4X4MatrixRightMul(temp1);
U4X4MatrixRightMul(temp2);
}
};
unsigned long BroadFibonacci_v1(const unsigned long &n, const unsigned long &x, const unsigned long &y){
unsigned tempF, tempA;
unsigned Fnminus1(1), Fnminus2(1);
unsigned Anminus1(2), Anminus2(1);
for (int i(2); i <n; i++){
tempF = Fnminus1;
Fnminus1= y*Fnminus1 + x*Fnminus2;
Fnminus2 = tempF;
tempA = Anminus1;
Anminus1 = y*Anminus1 + x*Anminus2 + (1-y)*Fnminus2 + Fnminus1;
Anminus2 = tempA;
}
return Anminus1;
}
unsigned long BroadFibonacci_v2(const unsigned long &n, const unsigned long &x, const unsigned long &y){
unsigned long MatrixArray[4][4] = {
{ y, x, 1, x },
{ 1, 0, 0, 0 },
{ 0, 0, y, x },
{ 0, 0, 1, 0 }
};
U4X4Matrix _4x4Matrix(MatrixArray);
_4x4Matrix.U4X4Matrix_Power_N(n - 2);
return _4x4Matrix.A[0][0] * 2 + _4x4Matrix.A[0][1] + _4x4Matrix.A[0][2] + _4x4Matrix.A[0][3];
}
int main(){
unsigned long x,y;
unsigned long n;
cout << "输入系数x、y和序数n,以空格键分隔" << endl;
cin >> x >> y>>n;
cout<<"BroadFibonacci_v1结果:"<<BroadFibonacci_v1(n, x, y)<<endl;
cout <<"BroadFibonacci_v2结果:" << BroadFibonacci_v2(n, x, y) << endl;
system("pause");
}
算法说明:
令 An=F0∗Fn+F1∗Fn−1+…+Fi∗Fn−i+…+Fn−1∗F1+FnF0 于是可以得到 An 的递推关系式:
An=X∗An−2+Y∗An−1+Fn+X∗Fn−1 ,这样就可以用自低向上的方法求出 An ,O(n)=n。
其实这个递推式还可以用矩阵来求解,可以将算法的时间复杂度降低到log(n):⎛⎝⎜⎜⎜AnAn−1FnFn−1⎞⎠⎟⎟⎟ = ⎛⎝⎜⎜⎜Y100X00010Y1X0X0⎞⎠⎟⎟⎟ ⎛⎝⎜⎜⎜An−1An−2Fn−1Fn−2⎞⎠⎟⎟⎟
可以化为:
⎛⎝⎜⎜⎜AnAn−1FnFn−1⎞⎠⎟⎟⎟ = ⎛⎝⎜⎜⎜Y100X00010Y1X0X0⎞⎠⎟⎟⎟n−2 ⎛⎝⎜⎜⎜A2A1F2F1⎞⎠⎟⎟⎟
A2=2,A1=1,F2=1,F1=1 。