标签:
1 //计算斐波那契数列 f(n) 2 3 #include <iostream> 4 #include <cmath> 5 using namespace std; 6 7 long fib1(int n){ 8 /*递归程序1:这种是最原始的想法,这样的做法会重复调用,做很多无用的工作。下面是优化的几种方法 */ 9 if (n <= 2){ 10 return 1; 11 } 12 else{ 13 return fib1(n-1) + fib1(n-2); 14 } 15 } 16 17 long fib(int n, long a, long b, int count){ 18 if (count == n) 19 return b; 20 return fib(n, b, a+b, ++count); 21 } 22 23 long fib2(int n){ 24 /* 递归程序2:这种递归的写法比fib1进步了不少,它略过了很多fib1中重复计算的部分。 25 但是递归写法,时间复杂度依然很高,近似为线性时间O(n),但比起下面的迭代循环仍然没有优势 */ 26 return fib(n, 0, 1, 1); 27 } 28 29 long fib3 (int n){ 30 /* 迭代解法:这里也可以将每次计算的结果存储下来,这就是大名鼎鼎的以“空间换时间”,这里算法复杂度显然为O(n) */ 31 long x = 0, y = 1; 32 for (int j = 1; j < n; j++){ 33 y = x + y; 34 x = y - x; 35 } 36 return y; 37 } 38 39 40 class Matrix{ 41 public: 42 long matr[2][2]; 43 Matrix(const Matrix&rhs); 44 Matrix(long a, long b, long c, long d); 45 Matrix& operator=(const Matrix&); 46 47 friend Matrix operator*(const Matrix& lhs, const Matrix& rhs){ 48 Matrix ret(0,0,0,0); 49 ret.matr[0][0] = lhs.matr[0][0]*rhs.matr[0][0] + lhs.matr[0][1]*rhs.matr[1][0]; 50 ret.matr[0][1] = lhs.matr[0][0]*rhs.matr[0][1] + lhs.matr[0][1]*rhs.matr[1][1]; 51 ret.matr[1][0] = lhs.matr[1][0]*rhs.matr[0][0] + lhs.matr[1][1]*rhs.matr[1][0]; 52 ret.matr[1][1] = lhs.matr[1][0]*rhs.matr[0][1] + lhs.matr[1][1]*rhs.matr[1][1]; 53 return ret; 54 } 55 }; 56 57 Matrix::Matrix(long a, long b, long c, long d){ 58 this->matr[0][0] = a; 59 this->matr[0][1] = b; 60 this->matr[1][0] = c; 61 this->matr[1][1] = d; 62 } 63 64 Matrix::Matrix(const Matrix &rhs){ 65 this->matr[0][0] = rhs.matr[0][0]; 66 this->matr[0][1] = rhs.matr[0][1]; 67 this->matr[1][0] = rhs.matr[1][0]; 68 this->matr[1][1] = rhs.matr[1][1]; 69 } 70 71 Matrix& Matrix::operator =(const Matrix &rhs){ 72 this->matr[0][0] = rhs.matr[0][0]; 73 this->matr[0][1] = rhs.matr[0][1]; 74 this->matr[1][0] = rhs.matr[1][0]; 75 this->matr[1][1] = rhs.matr[1][1]; 76 return *this; 77 } 78 79 Matrix power(const Matrix& m, int n){ 80 if (n == 1) 81 return m; 82 if (n%2 == 0) 83 return power(m*m, n/2); 84 else 85 return power(m*m, n/2) * m; 86 } 87 88 long fib4 (int n){ 89 /* 矩阵乘法:二分法进一步优化程序,时间复杂度为O(log(n)) */ 90 Matrix matrix0(1, 1, 1, 0); 91 matrix0 = power(matrix0, n-1); 92 return matrix0.matr[0][0]; 93 } 94 95 long fib5(int n){ 96 /* 公式法:终极必杀,直接套用表达式求解,时间复杂度为O(1). 97 不过有瑕疵的一点就是受制于库函数实现开方和乘方的效率,具体时间复杂度上考虑到上一点,估计也是 O(log(n)) */ 98 double z = sqrt(5.0); 99 double x = (1 + z)/2; 100 double y = (1 - z)/2; 101 return (pow(x, n) - pow(y, n))/z + 0.5; 102 } 103 104 int main(){ 105 cout << fib1(45) << endl; 106 cout << fib2(45) << endl; 107 cout << fib3(45) << endl; 108 cout << fib4(45) << endl; 109 cout << fib5(45) << endl; 110 return 0; 111 } 112 113
标签:
原文地址:http://www.cnblogs.com/liugl7/p/4858113.html