您的位置:首页 > 其它

<Sicily>Fibonacci 2

2016-06-08 00:14 357 查看

一、题目描述

In the Fibonacci integer sequence, F0 = 0, F1 = 1, and Fn = Fn-1 + Fn-2 for n ≥ 2. For example, the first ten terms of the Fibonacci sequence are:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, …

Given an integer n, your goal is to compute the last Fn mod (10^9 + 7).

二、输入

The input test file will contain a single line containing n (n ≤ 2^31-1).

There are multiple test cases!

三、输出

For each test case, print the Fn mod (10^9 + 7).

例如:

输入:9

输出:34

四、解题思路

这次要求输入的数会很大,使用递归或者动态规划的方法时,会超时。

所以只能使用矩阵方法求解。把问题转换为矩阵相乘,矩阵相乘可以通过快速幂的求解方法提高效率。

1、矩阵表示



2、矩阵推导公式



3、带入f(0),f(1)





由上面的公式能可知,可以把原问题转换成求一个矩阵的n次幂问题。

4、整数n次方的快速幂求法

例如求3的999次方





快速幂求法



5、使用同样的方法求一矩阵n次方

五、代码

#include <iostream>
using namespace std;

const long long int MODE = 1000000000+7;    //当数太大是取模(题目要求)

struct Matrix     //矩阵
{
long long int mat[2][2];
};

Matrix matrixMultiply(Matrix m1, Matrix m2) //两个矩阵乘积
{
Matrix result;

for(int i = 0; i < 2; i++)  //第i行(m1)
{
for(int j = 0; j < 2; j++)  //第j列(m2)
{
result.mat[i][j] = 0;
for(int k = 0; k < 2; k++)  //m1的第i行乘以m2的第j列
{
result.mat[i][j] += m1.mat[i][k] * m2.mat[k][j];
result.mat[i][j] %= MODE;
}
}
}

return result;
}

Matrix exponentiate(Matrix m1, long long int n) //矩阵的n次幂
{
Matrix result = {1, 0, 1, 0};
while(n)
{
if(n & 1) result = matrixMultiply(result, m1);  //当n为奇数时
m1 = matrixMultiply(m1, m1);
n >>= 1;
}

return result;
}

int main()
{
Matrix baseMatrix = {1, 1, 1, 0};
Matrix resultMatrix;
long long int n, fn;
while(cin >> n)
{
if(n == 0 || n == 1)
{
cout << n << endl;
continue;
}

resultMatrix = exponentiate(baseMatrix, n);
fn = resultMatrix.mat[0][1];
cout << fn << endl;
}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: