寻找解决斐波那契问题的好算法 递归方式给了我超出时间限制
示例输入: 70007 样品输出(最后一位数): 3
答案 0 :(得分:2)
这更像是一个数学问题,最近也发布了类似的问题。 Fibonacci数可以被认为是线性递归方程(递归定义)。在这种情况下,F(n)= F(n-1)+ F(n-2)。使用数组f表示F(n)和F(n-1),其矩阵形式为:
| 1 1 |
a = | 1 0 |
| 1 |
f(2) = | 1 |
f(i+1) = a f(i)
f(i+j) = a^j f(i)
这是基于F(0)= 0,F(1)= 1,F(2)= 1,F(3)= 2,F(4)= 3,F(5)= 5,F (6)= 8,......
要加快此过程,请使用重复平方将矩阵a提升到幂j。例如,a ^ 7 =(a * a ^ 2 * a ^ 4)。对于32位n,循环数为32.对于64位n,循环数为64。
然而,由于只要求最后一个数字,你做数学模10并且数学模10完成,结果证明a ^(j%60)= a ^ j(这是用a确定的)程序)。
f(i+j) = a^(j%60) f(i)
所以计算^(j%60)的循环次数最多为6.在我的系统上,计算任何32位或64位无符号整数n的fib(n)%10需要不到2微秒因为实际计算是f(n)=(a ^((n-2)%60)f(2))%10(所有数学运算都完成%10)。
这可以通过简单地索引包含f(0)到f(59)的最后一个数字的60个字符的预生成数组,然后将数组索引(n%60)来进一步加速。如果生成数组所花费的时间计算为计算时间的一部分,则一次性矩阵计算(最多6次循环)应该更快。
matix可以被反转并用于计算负的斐波纳契值,这些值具有相同的幅度,但具有交替的符号:
| 0 1 |
a^(-1) = | 1 -1 |
f(-6) = -8
f(-5) = 5
f(-4) = -3
f(-3) = 2
f(-2) = -1
f(-1) = 1
f( 0) = 0
f( 1) = 1
f( 2) = 1
f( 3) = 2
f( 4) = 3
f( 5) = 5
f( 6) = 8
如果没有模10,那么最大的32位无符号值是f(47)= 2971215073,最大的64位无符号值是f(93)= 12200160415121876738。
答案 1 :(得分:2)
如果您只需要最后一位数字,那么会有更快的方法,如示例输出中所示。由于我们正在查看最后一位数字,因此在我们开始重复之前,可能性有限。如果我们取f(1)= 1且f(2)= 1,则注意f(61)= 1而f(62)= 1是第一个重复对。换句话说,Fibonacci数的最后一位是一个长度为60的循环。计算前60位并将它们存储在一个数组中,然后返回数组的n mod 60元素。恒定时间。
答案 2 :(得分:1)
这里有两个问题。
n=70007
产生FP无穷大。答案 3 :(得分:1)
只需计算Fib数directly。我记得通过使用floor功能可以简化确切的公式,但我留给你研究这些问题。总结:直接公式很好。
答案 4 :(得分:-1)
#include <stdio.h>
#include <stdlib.h>
/*
* By Nedal Kouissi
* Fibonacci
* The Rfibonacci means that function use a recursive methode
* the Ifibonacci means that function use an iteration methode
*/
// finction prototype
unsigned long long int Ifibonacci( unsigned int );
// function prototype
unsigned long long int Rfibonacci( unsigned int );
int main(int argc, char** argv) {
unsigned int f = 1000000000000;
// display the results
printf( "Fibonacci( %u ) = %llu\n", f, Ifibonacci( f ) );
return (EXIT_SUCCESS);
}
unsigned long long int Ifibonacci( unsigned int x ) {
if ( x == 0 || x == 1 )
return x;
unsigned int i;
int prevP = 0;
int prev = 1;
int result;
for ( i = 2; i <= x ; ++i ) {
result = prevP + prev;
prevP = prev;
prev = result;
} // end for
return result;
} // end function Ifibonacci
unsigned long long int Rfibonacci( unsigned int x ) {
if ( x == 0 || x == 1 )
return x;
else // recursive step
return Rfibonacci( x - 1 ) + Rfibonacci( x - 2 );
} // end function Rfibonacci