poj3070斐波那契数列求解
2016-09-11 22:41
148 查看
问题
先看下面的问题: [ poj-3070]Description:
In the Fibonacci integer sequence, F0 = 0, F1 = 1, and Fn = Fn − 1 + Fn − 2 for n ≥ 2. For example, the first ten terms of the Fibonacci sequence are:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, …
Given an integer n, your goal is to compute the last 4 digits of Fn.
Input
The input test file will contain multiple test cases. Each test case consists of a single line containing n (where 0 ≤ n ≤ 1,000,000,000). The end-of-file is denoted by a single line containing the number −1.
Output:
For each test case, print the last four digits of Fn. If the last four digits of Fn are all zeros, print ‘0’; otherwise, omit any leading zeros (i.e., print Fn mod 10000).
Sample Input
0
9
999999999
1000000000
-1
Sample Output
0
34
626
6875
思路
之前讲过的矩阵快速幂求模求解即可。只不过本题在题目描述的过程中给出了另外一种矩阵表示。见下面证明:[F2F1F1F0]=[1110](1)
由于(1)恒成立,所以当n>=1时,等式两边同乘右边的常数矩阵,有:
[Fn+1FnFnFn−1]=[1110]n(2)
本质是求解如下矩阵:
[1110]n(3)
从而将斐波那契数列问题转化为矩阵乘法的问题,又可以进一步转化为矩阵快速幂。根之前的区别只是最终求解矩阵的区别。
代码
#include <iostream> #include <cstring> #include <fstream> //#define LOCAL const int maxn = 8; const int MOD = 10000; struct Matrix{ int mat_[maxn][maxn]; int size_; Matrix( int s = 0 ) : size_( s ) { std::memset( mat_, 0, sizeof(mat_) ); } Matrix( const Matrix& rhs ) { size_ = rhs.size_; *this = rhs; } int init() { mat_[0][0] = 1; mat_[0][1] = 1; mat_[1][0] = 1; mat_[1][1] = 0; return 0; } int set_diag( int val ) { for( int i = 0; i < size_; ++i ) { for( int j = 0; j < size_; ++j ) mat_[i][j] = (i==j)?val:0; } return 0; } Matrix& operator=( const Matrix& rhs ) { for( int i = 0; i < size_; ++i ) { for( int j = 0; j < size_; ++j ) mat_[i][j] = rhs.mat_[i][j]; } return *this; } Matrix operator*( const Matrix& rhs ) { Matrix ret(2); for( int i = 0; i < size_; ++i ) { for( int j = 0; j < size_; ++j ) { for( int index = 0; index < size_; ++index ) { ret.mat_[i][j] = (ret.mat_[i][j] + (mat_[i][index]%MOD * rhs.mat_[index][j]%MOD)%MOD)%MOD; } } } return ret; } Matrix& operator^( int b ) { Matrix a(*this); Matrix ans(2); ans.set_diag(1); while(b) { if(b%2) ans = ans * a; a = a*a; b /= 2; } *this = ans; return *this; } }; int main( void ) { #ifdef LOCAL std::ifstream cin("input.dat"); #endif int n = 0; while( std::cin >> n, n != -1 ) { if(!n) std::cout << 0 << std::endl; else { Matrix a(2); a.init(); a^n; std::cout << a.mat_[0][1] << std::endl; } } #ifdef LOCAL cin.close(); #endif return 0; }
总结
一遍过,没有遇见太大问题。感受到了引入矩阵后对于问题的简化。矩阵真是个好东西。相关文章推荐
- 求解斐波那契数列
- 基于特征值的斐波那契数列求解
- 斐波那契数列的几种求解方法
- 用递归,迭代,通项公式三种方法实现斐波那契数列求解
- 第十二周项目3 递归函数求解4 (我要知斐波那契数列)
- 矩阵快速幂求解任意初始值f1,f2及a,b的斐波那契数列
- 3种方法求解斐波那契数列
- 矩阵快速幂求斐波那契数列 poj3070
- 【算法02】3种方法求解斐波那契数列
- 二分法求解超大项的斐波那契数列数值
- python求解斐波那契数列
- [斐波那契数列 求解二次剩余&二次模方程 BSGS] COGS 2114 [CodeChef FN]斐波那契数
- 求解斐波那契数列的几种方法
- Java算法--递推算法 求解兔子产子问题或斐波那契数列问题
- 斐波那契数列的几种求解方式和复杂度分析
- (DP)斐波那契数列的动态规划求解(Fibonacci Dynamic Programming)
- 动态规划入门之求解斐波那契数列
- 利用矩阵快速幂求解斐波那契数列
- 非递归求解斐波那契数列第n项的值
- 斐波那契数列求解