斐波那契序列更快,但起始数不同(F [n] = F [n-1] + F [n-2])

时间:2018-05-19 21:22:36

标签: c++ c++14 sequence fibonacci sequences

(初学者)

我想知道如何找到第n个序列F [n] = F [n-1] + F [n-2]。

输入:

F[0] =  a;
F[1] =  b;
a,b < 101
N < 1000000001 
M < 8; M=10^M;

a和b是起始序列号。

n是我需要找到的序列的第n个数字。

M是模数,数字变得非常快,所以F [n] = F [n]%10 ^ M,我们找到余数,因为只需要第n个数字的最后一位数

递归方法太慢了:

int fib(int n)
{
   if (n <= 1)
      return n;
   return fib(n-1) + fib(n-2);
}

花费O(n)时间的动态编程解决方案也太慢了:

f[i] = f[i-1] + f[i-2];

虽然如果序列的第一个数字是0和1(第0个数字可以在O(log n)中找到),如果使用这个公式可以更快地找到第n个数字的解决方案:

If n is even then k = n/2:
F(n) = [2*F(k-1) + F(k)]*F(k)

If n is odd then k = (n + 1)/2
F(n) = F(k)*F(k) + F(k-1)*F(k-1)

(使用它链接到公式和代码实现:https://www.geeksforgeeks.org/program-for-nth-fibonacci-number/

但是如果起始数字类似于25和60,则此公式不起作用。并且递归方法太慢。

所以我想知道怎样才能找到比O(n)更快的序列的第n个数。部分代码会有所帮助。

谢谢。

1 个答案:

答案 0 :(得分:7)

这个矩阵:

A = / 1  1 \
    \ 1  0 /

当乘以列向量(f n + 1 ,f n )时,其中f n 是Fibonacci中的第n个数字序列,将给你列向量(f n + 2 ,f n + 1 ),即它会提前一步。无论序列的初始元素是什么,这都有效。

例如:

/ 1  1 \ / 8 \  =  / 13 \
\ 1  0 / \ 5 /     \ 8  /

所以第n个斐波纳契数是A n-1 v的第一个元素,其中v是包含f 1 且f 0的列向量,序列中的前两个数字。

因此,如果你能快速计算A n-1 模数某个数,这将给你f n 。这可以使用Exponentiation by squaring来完成,它在O(logn)中有效。只需确保在每次乘法和加法后执行模数,以防止数字变得过大。