如何在log(n)时间或更好的时间内计算该序列的第n个元素?

时间:2012-09-03 18:32:42

标签: c++ c fibonacci sequences

1 4 10 22 45 88 167

这个序列是斐波纳契数与自身的卷积。 重现是

a[n] = a[n-1] + a[n-2] + Fibonacci[n+2]

如果您假设Fibonacci序列从0,1,1,2,3,5 ...开始(http://oeis.org/A213587

如何生成它是对数时间还是更快? 请注意,这不是作业,也不是任何比赛问题。我正在研究Fibonacci应用序列。

3 个答案:

答案 0 :(得分:2)

这是一个封闭的公式,因此几乎保证为O(1)(使用Mathematica计算)

<强>输入

RSolve[{a[n] == a[n - 2] + a[n - 1] + Fibonacci[n + 2], a[1] == 1, a[2] == 4}, a[n], n]

输出(点击here查看完整尺寸):

link

您将不得不使用一些浮点算术,但您仍然可以从double数据类型获得更高的精度。如果精度是个问题,请使用GMP或其他任意精度库。

答案 1 :(得分:1)

这不是问题的实际答案,只是在O(n)

中生成整个序列的方法

如果您只计算O(log(n))时间复杂度来计算第n个元素,而不是全部到n它实际上非常容易。如果你遍历,你可以通过适当的记忆轻松地为每个元素做O(1)

我想这个:

a[1] = 1, a[2] = 1, fib[1] = 0, fib[2] = 1, fib[3] = 1

然后在此过程中迭代并记住a[n-1]a[n-2]以及fib[n-1]fib[n-2]

long an_1 = 1;  // a[2]
long an_2 = 1;  // a[1]
long fib_1 = 2; // fib[4]
long fib_2 = 1; // fib[3]

// Starts with a[3]
while (true)
{
    long fib = fib_1 + fib_2;
    long an = an_1 + an_2 + fib;

    std::cout << an;

    fib_2 = fib_1;
    fib_1 = fib;
    an_2 = an_1;
    an_1 = an;
}

修改 :这称为amortized complexity。计算最多n个元素需要O(n)个步骤,但是当您到达此点时,您可以使用1n的所有元素,计算每个元素的成本是O(1)。正式的证据有点详细,但这就是这个想法。

答案 2 :(得分:1)

通过将递归关系转换为斐波那契卷积,我能够在log n时间内解决这个问题。最后,递归关系仅包含Lucas数和Fibonacci数。所以我能够在2 * log中解决它一旦我弄清楚如何在这里写出数学符号,我就会在这里写出整个证据。