编程之美: 第二章 数字之魅 2.9斐波那契数列
2015-08-02 00:18
411 查看
/* 斐波那契数列: 解法二:求通项公式的特征方程为 x^2 = x + 1 所以x1,2 = (1+ - 根号5 )/2; 所以存在A,B使得 F(n) = A*((1+根号5)/2)^n + b*((1-根号5)/2)^n 带入F(0)=0,F(1) = 1 解得A = 根号5/5,B= -根号5/5 F(n) = 根号5/5 * ((1+根号5)/2)^n - 根号5/5 * ((1-根号5)/2)^n 可以在O(1)时间得到F(n) 解法三: 分治策略 注意Fibonacci是二阶递推数列,存在一个2*2矩阵A,使得 (Fn,Fn-1) = (Fn-1,Fn-2)*A = (F1,F0)*A^(n-1),A= [1 1],F1 = 1,F0 = 0 [1 0] 输入: 11 输出: 89 */ /* guanjian : 1 matrixOrigin = power_matrix(matrixOrigin,n-1);//注意Fibonacci是二阶递推数列,存在一个2*2矩阵A,使得 //(Fn,Fn-1) = (Fn-1,Fn-2)*A = (F1,F0)*A^(n-1),A= [1 1],F1 = 1,F0 = 0 // [1 0]注意Fibonacci是二阶递推数列,存在一个2*2矩阵A,使得 //(Fn,Fn-1) = (Fn-1,Fn-2)*A = (F1,F0)*A^(n-1),A= [1 1],F1 = 1,F0 = 0 // [1 0] 2 Matrix operator*(const Matrix& rhs)//定义矩阵乘法 { Matrix ret(0,0,0,0); ret._lMatrix[0][0] = _lMatrix[0][0] * rhs._lMatrix[0][0] + _lMatrix[0][1] * rhs._lMatrix[1][0];//参见举证乘法运算 3 Matrix ret(1,0,0,1); Matrix tmp = m; for( ; n ; n >>= 1 )//循环的结束条件是n为0,每次n都除以2 { if(n & 1)//如果n为奇数,等于把最后一次的值乘起来 { ret = ret * tmp; } tmp = tmp * tmp; 4 double a = pow( (1.0 + sqrt(5.0))/2.0,n);//F(n) = 根号5/5 * ((1+根号5)/2)^n - 根号5/5 * ((1-根号5)/2)^n */ #include <stdio.h> #include <iostream> #include <math.h> using namespace std; class Matrix { public: long long _lMatrix[2][2]; Matrix(long long a,long long b,long long c,long long d) { _lMatrix[0][0] = a; _lMatrix[0][1] = b; _lMatrix[1][0] = c; _lMatrix[1][1] =d; } Matrix& operator=(const Matrix& other) { if(this != &other) { _lMatrix[0][0] = other._lMatrix[0][0]; _lMatrix[0][1] = other._lMatrix[0][1]; _lMatrix[1][0] = other._lMatrix[1][0]; _lMatrix[1][1] = other._lMatrix[1][1]; } return *this; } Matrix operator*(const Matrix& rhs)//定义矩阵乘法 { Matrix ret(0,0,0,0); ret._lMatrix[0][0] = _lMatrix[0][0] * rhs._lMatrix[0][0] + _lMatrix[0][1] * rhs._lMatrix[1][0];//参见举证乘法运算 ret._lMatrix[0][1] = _lMatrix[0][0] * rhs._lMatrix[0][1] + _lMatrix[0][1] * rhs._lMatrix[1][1]; ret._lMatrix[1][0] = _lMatrix[1][0] * rhs._lMatrix[0][0] + _lMatrix[1][1] * rhs._lMatrix[1][0]; ret._lMatrix[1][1] = _lMatrix[1][0] * rhs._lMatrix[0][1] + _lMatrix[1][1] * rhs._lMatrix[1][1]; return ret; } }; Matrix power_matrix(Matrix& m,int n)//O(log2N) { Matrix ret(1,0,0,1); Matrix tmp = m; for( ; n ; n >>= 1 )//循环的结束条件是n为0,每次n都除以2 { if(n & 1)//如果n为奇数,等于把最后一次的值乘起来 { ret = ret * tmp; } tmp = tmp * tmp; } return ret; } long long fibonacci_matrix(int n) { Matrix matrixOrigin(1,1,1,0); matrixOrigin = power_matrix(matrixOrigin,n-1);//注意Fibonacci是二阶递推数列,存在一个2*2矩阵A,使得 //(Fn,Fn-1) = (Fn-1,Fn-2)*A = (F1,F0)*A^(n-1),A= [1 1],F1 = 1,F0 = 0 // [1 0]注意Fibonacci是二阶递推数列,存在一个2*2矩阵A,使得 //(Fn,Fn-1) = (Fn-1,Fn-2)*A = (F1,F0)*A^(n-1),A= [1 1],F1 = 1,F0 = 0 // [1 0] return matrixOrigin._lMatrix[0][0];//其实应该返回F1*an(0,0) + F0*an(1,0),但是由于F1为1,F0 = 0简化了 } long long fibonacci_equation(int n) { double f = sqrt(5.0)/5.0; double a = pow( (1.0 + sqrt(5.0))/2.0,n);//F(n) = 根号5/5 * ((1+根号5)/2)^n - 根号5/5 * ((1-根号5)/2)^n double b = pow( (1.0 - sqrt(5.0))/2.0,n); double dRes = f*(a - b); return (long long)dRes; } void process() { int n; while(EOF != scanf("%d",&n)) { printf("%lld\n",fibonacci_equation(n)); printf("%lld\n",fibonacci_matrix(n)); } } int main(int argc,char* argv[]) { process(); getchar(); return 0; }
相关文章推荐
- 编程之美:第二章 数字之魅 2.8找到符合条件的整数
- 编程之美:第二章 数字之魅 2.6精确表达浮点数
- 编程之美: 第二章 数字之魅 2.4 1的数目
- 编程之美: 第二章 数字之魅 2.7最大公约数问题
- JAVA集合框架的总结(集合嵌套)
- C语言之函数调用17—递归法之一般函数的调用(2)
- django book学习笔记――模板
- 编程之美:第二章 数字之魅 2.3寻找发帖水王
- 编程之美:第二章 数字之魅 2.5寻找最大的k个数
- MFC exe使用C++ dll中的std::string 崩溃
- 编程之美: 第二章 数字之魅 2.3_1寻找发帖超过总帖1/4的水王
- JAVA中的数据类型和变量
- 编程之美: 第二章 数字之魅 2.2不要被阶乘吓到
- 编程之美: 第二章 数字之魅 2.1求二进制数中1的个数
- 编程之美: 第一章 1.16 24点游戏
- 编程之美:第一章 1.17俄罗斯方块游戏
- ASP.NET MVC 小牛之旅2:体验第一个MVC程序
- 01_JNI是什么,为什么使用,怎么用JNI,Cygwin环境变量配置,NDK案例(使用Java调用C代码),javah命令使用
- 01_JNI是什么,为什么使用,怎么用JNI,Cygwin环境变量配置,NDK案例(使用Java调用C代码),javah命令使用
- PHP 7新特性介绍