本文已参与「新人创作礼」活动,一起开启掘金创作之路。
求斐波那契数列的第n项
题目描述
求斐波那契数列的第n项(第0项为0,第一项为1),由于结果可能很大,所以需要对结果取模(1e9+7) 其中0<=n<100000
解法一:递归+记忆化,时间复杂度:O(n)
递归加记忆化方法很简单,直接贴代码
#include <iostream>
using namespace std;
const int MOD = 1e9+7, N = 1e5+10;
int mem[N];
int fib(int n) {
if (n == 0) return 0;
if (n == 1) return 1;
if(mem[n]) return mem[n];
mem[n] = (fib(n - 1) + fib(n - 2)) % MOD;
return mem[n];
}
int main() {
int n;
cin >> n;
cout << fib(n) << endl;
return 0;
}
解法二:矩阵快速幂,时间复杂度:O(logn)
由上述公式即可求出的值,而可以利用快速幂求解,求解时间复杂度为O(logn),所以整体的时间复杂度就为O(logn)
#include <iostream>
using namespace std;
const int MOD = 1e9+7;
struct matrix {
int a00, a01, a10, a11;
matrix(int a, int b, int c, int d) {
a00 = a;
a01 = b;
a10 = c;
a11 = d;
}
matrix() {
a00 = 1;
a01 = 0;
a10 = 0;
a11 = 1;
}
};
const matrix matr = {1, 1, 1, 0};
matrix mult(matrix a, matrix b) {
matrix res;
res.a00 = (a.a00 * b.a00 % MOD + a.a01 * b.a10 % MOD) % MOD;
res.a01 = (a.a00 % MOD * b.a01 + a.a01 * b.a11 % MOD) % MOD;
res.a10 = (a.a10 % MOD * b.a00 + a.a11 * b.a10 % MOD) % MOD;
res.a11 = (a.a10 % MOD * b.a01 + a.a11 * b.a11 % MOD) % MOD;
return res;
}
matrix qmi(int t) {
matrix res;
matrix temp = matr;
while(t) {
if(t & 1) res = mult(res, temp);
temp = mult(temp, temp);
t >>= 1;
}
return res;
}
int main() {
int n;
cin >> n;
if(n == 0) {
cout << 0 << endl;
return 0;
}
if(n == 1) {
cout << 1 << endl;
return 0;
}
matrix res = qmi(n - 1);
int ans = res.a00;
cout << ans << endl;
return 0;
}