斐波那契数列问题的解

解法一:递归

1 int Fib(int n)
2 {
3     if (n <= 0)
4         return 0;
5     else if (n == 1)
6         return 1;
7     else
8         return Fib(n - 1) + Fib(n - 2);
9 }

解法二:递推

 1 int Fib(int n)
 2 {
 3     if (n <= 0)
 4         return 0;
 5     else if (n == 1)
 6         return 1;
 7 
 8     int first = 0, second = 1;
 9     int res = 0;
10     for (int i = 1; i < n; ++i) {
11         res = first + second;
12         first = second;
13         second = res;
14     }
15     return res;
16 }

解法三:分治

通项之间有如下关系:

其中矩阵A为:

根据以下公式,可以log(n)次乘法计算出An

 1 class Matrix {
 2 public:
 3     Matrix() : m00(0), m01(0), m10(0), m11(0) {}
 4     Matrix(int m00, int m01, int m10, int m11) : 
 5             m00(m00), m01(m01), m10(m10), m11(m11) {}
 6     Matrix& operator=(const Matrix& m) {
 7         this->m00 = m.m00;
 8         this->m01 = m.m01;
 9         this->m10 = m.m10;
10         this->m11 = m.m11;
11         return *this;
12     }
13 
14     int m00;
15     int m01;
16     int m10;
17     int m11;
18 };
19 Matrix operator*(const Matrix& lhs, const Matrix& rhs)
20 {
21     Matrix res;
22     res.m00 = lhs.m00 * rhs.m00 + lhs.m01 * rhs.m10;
23     res.m01 = lhs.m00 * rhs.m01 + lhs.m01 * rhs.m11;
24     res.m10 = lhs.m10 * rhs.m00 + lhs.m11 * rhs.m10;
25     res.m11 = lhs.m10 * rhs.m01 + lhs.m11 * rhs.m11;
26     return res;
27 }
28 
29 Matrix MatrixPow(const Matrix& m, int n)
30 {
31     Matrix res(1, 0, 0, 1);
32     Matrix base = m;
33     for (; n; n >>= 1) {
34         if (n & 1)
35             res = res * base;
36         base = base * base;
37     }
38     return res;
39 }
40 
41 int Fib(int n)
42 {
43     if (n <= 0)
44         return 0;
45     else if (n == 1)
46         return 1;
47 
48     Matrix A(1, 1, 1, 0);
49     Matrix m = MatrixPow(A, n - 1);
50 
51     return m.m00;
52 }

 函数MatrixPow的写法似乎不像分治,实际上我们把它写成下面这样就比较明显了,时间复杂度O(logn)。

1 Matrix MatrixPow(const Matrix& m, int n)
2 {
3     if (n == 1)
4         return m;
5     if (n % 2 == 0)
6         return MatrixPow(m * m, n / 2);
7     else
8         return MatrixPow(m * m, n / 2) * m;
9 }

 

posted @ 2015-07-07 10:45  QingLiXueShi  阅读(208)  评论(0编辑  收藏  举报