AtCoderの企業コンテスト
次の企業コンテストの問題へ
天下一プログラマーコンテスト2013 決勝 A 天下一有無
C#のソース
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("2 2");
//4
}
else if (InputPattern == "Input2") {
WillReturn.Add("3 2");
//10
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static int[] GetSplitArr(string pStr)
{
return (pStr == "" ? new string[0] : pStr.Split(' ')).Select(pX => int.Parse(pX)).ToArray();
}
const int Hou = 1000000007;
static int mYoko;
static int mTate;
static int AllBitOn;
static void Main()
{
List<string> InputList = GetInputList();
int[] wkArr = GetSplitArr(InputList[0]);
int N = wkArr[0];
int M = wkArr[1];
mYoko = Math.Max(N, M);
mTate = Math.Min(N, M);
AllBitOn = (1 << mYoko) - 1;
List<int> YokoList = DeriveYokoList();
// 場合の数[上のBit列]なDP表
int[] PrevDP = new int[AllBitOn + 1];
PrevDP[0] = 1;
for (int I = 1; I <= mTate; I++) {
int[] CurrDP = new int[AllBitOn + 1];
for (int J = 0; J <= AllBitOn; J++) {
if (PrevDP[J] == 0) continue;
string BinStr1 = Convert.ToString(J, 2);
BinStr1 = BinStr1.PadLeft(mYoko, '0');
foreach (int EachYoko in YokoList) {
string BinStr2 = Convert.ToString(EachYoko, 2);
BinStr2 = BinStr2.PadLeft(mYoko, '0');
bool IsOK = true;
for (int K = 0; K <= BinStr2.Length - 1; K++) {
if (BinStr2[K] == '0') continue;
int Ind1 = K - 1;
int Ind2 = K;
int Ind3 = K + 1;
if (0 <= Ind1 && BinStr1[Ind1] == '1') IsOK = false;
if (BinStr1[Ind2] == '1') IsOK = false;
if (Ind3 <= BinStr1.Length - 1 && BinStr1[Ind3] == '1') IsOK = false;
if (IsOK == false) break;
}
if (IsOK) {
CurrDP[EachYoko] += PrevDP[J];
CurrDP[EachYoko] %= Hou;
}
}
}
PrevDP = CurrDP;
}
int Answer = 0;
for (int I = 0; I <= AllBitOn; I++) {
Answer += PrevDP[I];
Answer %= Hou;
}
Answer--; // 0の分を引く
if (Answer > 0) {
Answer += Hou;
}
Answer %= Hou;
Console.WriteLine(Answer);
}
// 横に配置する候補のList
static List<int> DeriveYokoList()
{
var YokoList = new List<int>();
for (int I = 0; I <= AllBitOn; I++) {
string BinStr = Convert.ToString(I, 2);
if (BinStr.Contains("11")) {
continue;
}
YokoList.Add(I);
}
return YokoList;
}
}
解説
行ごとに決めていくbitDPで、
場合の数[上のBit列]なDP表を更新してます。
計算量は、15*(2^15) なので、間に合います。