斐波那契数列
来源:互联网 发布:淘宝怎么交保证金 编辑:程序博客网 时间:2024/06/02 06:20
我们知道斐波那契数列:1 1 2 3 5 8 13 ……
这个可以通过递归或DP来实现。但是如果我们要求第10^9个斐波那契数列怎么办?
这就没办法用递归去跑了。
这里则有一个求矩阵幂方法。我们先记住公式……
[Fn+1, Fn = [1 1 的 n 次方
Fn-1, Fn ] 1 0 ]
那么则可以把Fn表示成多个矩阵相乘的形式。
然后我们要做的,是求矩阵的 n 次幂:
A^n = A^(n/2) * A^(n/2) ,当n为偶数
A^n = A^((n-1)/2) * A^((n-1)/2) * A,当n为奇数
通过这种方式可以将复杂度降到 log(n)。
然后,这里涉及到两个矩阵相乘,如果两个矩阵可以相乘,比如A,B相乘。
则说明A的列等于B的行。
我们知道公式 Cij = k求和 { Aik * Bkj }
至此,完成了我们的思路,下面是代码。
class Solution {public: struct mat { int m[2][2]; }; int Fibonacci(int n) { mat base; base.m[0][0] = 1; base.m[0][1] = 1; base.m[1][0] = 1; base.m[1][1] = 0; mat res = expMatrix(base, n); return res.m[0][1]; } mat expMatrix(mat base, int n) { if (0 == n) { mat res; res.m[0][0] = 1; res.m[0][1] = 0; res.m[1][0] = 0; res.m[1][1] = 1; return res; } if (1 == n) { return base; } mat res = expMatrix(base, n >> 1); res = mulMatrix(res, res); if (1 == n % 2) { res = mulMatrix(res, base); } return res; } mat mulMatrix(mat a, mat b) { mat res; memset(res.m, 0, sizeof(res.m)); for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { for (int k = 0; k < 2; k++) { res.m[i][j] += a.m[i][k] * b.m[k][j]; } } } return res; }};
阅读全文
0 0
- 斐波那契数列数列计算
- 斐波那契数列
- 斐波那契数列
- 斐波那契数列
- 斐波那契数列
- 斐波那契数列
- 斐波那契数列
- 斐波那契数列
- 斐波那契数列
- 斐波那契数列
- 斐波那契数列
- 斐波那契数列
- 斐波那契数列
- 斐波那契数列
- 斐波那契数列
- 斐波那契数列
- 斐波那契数列
- 斐波那契数列
- NGINX负载均衡分发请求的几种方式
- shrio 权限管理filterChainDefinitions过滤器配置
- NIO知识一 Java NIO(New I/O)的三个属性position、limit、capacity
- 用nginx的反向代理机制解决前端跨域问题
- HTTP协议及Java实践
- 斐波那契数列
- Kotlin 中创建类似 Java 的静态工具方法
- SQL—EXISTS的用法(转)
- Python处理DICOM(01)--基础环境搭建
- Hadoop上Data Locality
- anaconda的安装与使用
- oracle笔记总结
- [转载]Android APK反编译就这么简单 详解(附图)
- C++ 运算符重载