トップページに戻る    次の競技プログラミングの問題へ    前の競技プログラミングの問題へ

No.314 ケンケンパ

■■■問題■■■

たろうくんはケンケンパが好きです。
ケンケンパとは片足跳びの「ケン」と両足着地の「パ」とを繰り返す遊びです。

今、たろうくんは長さNの新しいケンケンパコースを作ろうと考えています。
楽しいケンケンパコースにするために、次の2つの条件を守ってコースを作らないといけません。

1.「ケン」は3回以上続いてはいけない
2.「パ」は「ケン」のあとにしか置けない

たろうくんは何通りのコースが作れるのか気になっていますが、幼稚園児なので計算がうまくできません。

そこで、たろうくんの代わりに何通りのコースが作れるかを求めてあげてください。
ただし、答えは非常に大きくなる可能性があるので1000000007で割った余りを出力してください。

■■■入力■■■

N

Nは1以上100万以下の整数です

■■■出力■■■

何通りのコースが作れるか、1000000007で割った余りを出力してください


C#のソース

using System;
using System.Collections.Generic;

class Program
{
    static string InputPattern = "InputX";

    static List<string> GetInputList()
    {
        var WillReturn = new List<string>();

        if (InputPattern == "Input1") {
            WillReturn.Add("3");
            //2
            //「ケンケンパ」と「ケンパケン」の2通りがありえます
        }
        else if (InputPattern == "Input2") {
            WillReturn.Add("4");
            //3
            //「ケンケンパケン」と「ケンパケンパ」と「ケンパケンケン」
            //の3通りがありえます。
        }
        else if (InputPattern == "Input3") {
            WillReturn.Add("100");
            //831891005
        }
        else {
            string wkStr;
            while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
        }
        return WillReturn;
    }

    static void Main()
    {
        const long Hou = 1000000007;

        List<string> InputList = GetInputList();
        int N = int.Parse(InputList[0]);

        //場合の数[連続したケンの数]なDP表
        int UB = 2;

        long[] PrevDP = new long[UB + 1];
        PrevDP[0] = 1;

        for (int I = 1; I <= N; I++) {
            long[] CurrDP = new long[UB + 1];
            for (int J = 0; J <= UB; J++) {
                if (PrevDP[J] == 0) continue;

                //パにする場合
                if (J > 0) {
                    CurrDP[0] += PrevDP[J];
                    CurrDP[0] %= Hou;
                }

                //ケンを続ける場合
                if (J < 2) {
                    CurrDP[J + 1] += PrevDP[J];
                    CurrDP[0] %= Hou;
                }
            }
            PrevDP = CurrDP;
        }

        long Answer = 0;
        foreach (long EachLong in PrevDP) {
            Answer += EachLong;
            Answer %= Hou;
        }
        Console.WriteLine(Answer);
    }
}


解説

配る動的計画法で解いてます。