トップページに戻る
次の競技プログラミングの問題へ
前の競技プログラミングの問題へ
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);
}
}
解説
配る動的計画法で解いてます。