0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AtCoderをゆっくり解く ABC079B編

Last updated at Posted at 2017-11-25

問題はこちら

この問題も、標準入力から整数を1つだけ受け取ります。

<?php
    fscanf(STDIN, "%d", $N);

リュカ数を、再帰呼び出しで計算してみましょう。

再帰呼び出しとは、関数自身を呼び出して処理を行う手法です。

$L[0]は、2です。
$L[1]は、1です。
$L[i]は、$L[i-1]と$L[i-2]を足したものです。

これをそのまま、実装して行きます。

    function calcL($n) {
        switch ($n) {
            case 0:
                return 2;
                break;
            case 1:
                return 1;
                break;
            default:
                return calcL($n - 1) + calcL($n - 2);
        }
    }

完成しました。それでは、paiza.ioで試しに実行してみます。
やってみると、入力例2の「86」でタイムアウトになってしまいます。
なぜでしょうか?
これは、calcL(86)実行時にcalcL(85)とcalcL(84)が呼び出され、calcL(85)の処理でcalcL(84)とcalcL(83)が呼び出され……となるのですが、1回計算されたcalcL(84)などがあったとしても、それを無視してまた別にcalcL(84)の計算をしようとするので、膨大な量の計算が発生してしまうからです。

……という訳で、一度計算した結果はとっておき、それを利用するように改造します。

    function calcL($n) {
        global $array;
        $array[0] = 2;
        $array[1] = 1;
        if (isset($array[$n])) {
            return $array[$n];
        } else {
            $array[$n] = calcL($n - 1) + calcL($n - 2);
            return $array[$n];
        }
    }

関数のローカル変数は再帰呼び出しの際にスコープの違いにより参照されなくなってしまいますので、グローバルの変数(配列) $array を設定しています。

さきほどのプログラムでは1分経っても答えは返ってきませんが、改造した方のプログラムでは、0.03秒ほどで計算結果が表示されます。

paiza.ioでのURL

AtCoderでの実行結果

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?