求解f(n)= 2 *(f(n-1)+ f(n-2))mod 1000000007的算法

时间:2012-07-05 07:57:17

标签: algorithm recurrence

  

可能重复:
  I want to generate the nth term of the sequence 1,3,8,22,60 ,164 in Order(1) or order of (nlogn)
  Calculate the nth term of the sequence 1,3,8,22,60,164,448,1224…?

我有一个递归关系f(n)= 2 *(f(n-1)+ f(n-2))。我必须求f(k)mod 1000000007,其中k是输入。 k的范围是1 <= k <= 1000000000?。我试过通过简单的递归函数实现它,但显然它导致大k的溢出,因此我遇到运行时错误。我是算法和新手的新手,所以需要知道是否存在解决此类问题的具体而有效的方法?

#include<stdio.h>
#define M 1000000007
long long unsigned res(long long unsigned n){
  if(n==1)
    return 1;
  else {
    if(n==2)
      return 3;
    else return (2*(res(n-1)%M+res(n-2)%M));
  }
}
int main(){
  int test;
  scanf("%d",&test);
  while(test--){
    long long unsigned n;
    scanf("%llu",&n);
    printf("%llu\n",res(n));
  }
  getch();
  return 0;
} 

2 个答案:

答案 0 :(得分:0)

您可以使用以下两个身份:

mod(a * b, p) = mod(mod(a, p) * mod(b, p), p)
mod(a + b, p) = mod(mod(a, p) + mod(b, p), p)

这给了你,假设mod(2,p)= 2:

mod(f(n), p) = mod(2 * mod(mod(f(n - 1), p) + mod(f(n - 2), p), p), p)

或更简单:

mod(f(n), p) = mod(mod(2 * f(n - 1), p) + mod(2 * f(n - 2), p), p)

从那里计算f(k)应该很容易。并且不需要递归,你可以做一个线性分辨率(这只是斐波纳契数列的变化)。

提示:尝试将f(n - 1)f(n - 2)保留在本地人中,从中计算f(n),然后更新您的本地人并进行迭代。

答案 1 :(得分:0)

首先,你必须定义f(0)和f(1)会发生什么,因为在某些时候你会到达它们。 然后你可以解决它前进而不是后退。从2开始向前走,直到你以这种方式到达k:

f(k) {
    a = F0; // F0 is the predefined value f(0)
    b = F1; // F1 is the predefined value f(1)
    if ( k == 0 ) {
       return a;
    }
    else if ( k == 1 ) {
       returb b;
    }
    else {
       n = 2;
       while ( n < k ) {
          c=2*(a+b);
          a=b;
          b=c;
          n = n+1;
       }
       return c;
    }
}

如果你多次调用它,你应该考虑将所有c保存在某个地方,这样你就不必每次都重新计算它。 我希望我很清楚。否则再问我一次