【问题标题】:Find the nth term of the recurrence relation, given the first 2 terms, f(0) and f(1) [closed]给定前 2 项 f(0) 和 f(1),找到递归关系的第 n 项
【发布时间】:2017-06-05 07:00:23
【问题描述】:

f(n) = f(n-1) + f(n-2) + f(n-1)*f(n-2);

1 1

以 10^9 + 7 为模输出答案。

我发现的通用术语是, f(n) = (((1 + f(1))^T(n)) * ((1 + f(0))^T(n-1))) - 1; 这里 T(n) 是第 n 个斐波那契数。

我使用矩阵求幂和模幂来解决问题,但它给出了 TLE。

【问题讨论】:

标签: java c++ c++11 recursion recurrence


【解决方案1】:

只要您没有提供代码示例,我就会给您一个大致的概念。

我个人不会使用递归,因为n 可能很大,从而导致填充堆栈的低效和长计算并导致溢出。所以最好用数组来实现一个循环。

下一个技巧是保持数字相对较小,对每一步进行模数计算。 (a+b+ab)%m 等于 (a%m + b%m + (a%m)*(b%m))%m(参见 wiki),因此我们将数字保持在 0..10^9 范围内

这里是一个解决方案的例子:

const unsigned int mod = 1e9+7;
std::vector<unsigned int> vec(n+1);    // prepare vector of needed size
                                       // size is n+1 because we start from 0 and you need vec[n]
vec[0] = 1;                            
vec[1] = 1e9;

unsigned long long int r1, r2;         // long long will prevent r1*r2 from overflowing
for (unsigned int i = 2; i <= n; ++i)
{
    r1 = vec[i-1] % mod;
    r2 = vec[i-2] % mod;
    vec[i] = (r1 + r2 + r1*r2) % mod;
}

std::cout << vec[n];

您使用 [c++] 和 [java] 标记了您的问题。上面的代码在 [c++] 中,我希望你能在需要时移植它

【讨论】:

    【解决方案2】:

    k=1000000007 是素数。所以a^b mod k 等价于a^(b mod (k-1))

    mod k,f(0)+1 为 2,f(1)+1 为 -6。

    通过重复平方和选择要相乘的正方形,可以有效地完成幂次​​运算。

    计算第 n 个斐波那契模 1000000006 很棘手(对于较大的 n)。我不知道一个简单的封闭形式。

    啊哈!皮萨诺周期是斐波那契数模某个值重复的周期。 k 被分解为素数 2 * 500,000,003

    只需计算 2 和 500000003 的Pisano period。取这两个素数的 pisano 周期的 LCM 即可得到它们乘积的 pisano 周期。我们可以使用它来减少值 n 以这个数字为模,然后再将它提供给斐波那契。

    这给了我们一个有界斐波纳契计算(希望易于处理),得到斐波纳契结果 mod 1000000006,然后我们可以使用平方技术(mod 1000000007)将 2 和 -6 提高到该幂,将它们加在一起并减 1。

    祝你好运计算皮萨诺周期。如果它是合理的(并且大多数看起来是合理的),您应该能够在几分之一秒内获取十亿位数的 n 并求解。

    现在,皮萨诺时期和斐波那契的封闭形式是基于一些数论和数学。因此,我们可以尝试直接为这种重复关系生成类似的数论/等结果,而不是通过您找到的身份。可以说这会更难,但可能会导致更清晰的答案。

    【讨论】:

      猜你喜欢
      • 2021-10-06
      • 2015-08-13
      • 1970-01-01
      • 2015-10-08
      • 2012-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多