-1

重複の可能性:
Order(1)または(nlogn)の順序でシーケンス1,3,8,22,60,164のn番目の項を生成したいシーケンス1,3,8,22
のn番目の項を計算します。 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;
} 
4

2 に答える 2

0

次の 2 つの ID を使用できます。

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)してから、ローカルを更新して反復するようにしてください。

于 2012-07-05T08:09:38.410 に答える