DPコンテスト
次のDPコンテストの問題へ
前のDPコンテストの問題へ
Educational DP Contest L Deque
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("4");
WillReturn.Add("10 80 90 30");
//10
}
else if (InputPattern == "Input2") {
WillReturn.Add("3");
WillReturn.Add("10 100 10");
//-80
}
else if (InputPattern == "Input3") {
WillReturn.Add("1");
WillReturn.Add("10");
//10
}
else if (InputPattern == "Input4") {
WillReturn.Add("10");
WillReturn.Add("1000000000 1 1000000000 1 1000000000 1 1000000000 1 1000000000 1");
//4999999995
}
else if (InputPattern == "Input5") {
WillReturn.Add("6");
WillReturn.Add("4 2 9 7 1 5");
//2
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static long[] mAArr;
static long UB;
static void Main()
{
List<string> InputList = GetInputList();
mAArr = InputList[1].Split(' ').Select(pX => long.Parse(pX)).ToArray();
UB = mAArr.GetUpperBound(0);
long Result = DFS(0, UB);
Console.WriteLine(Result);
}
// メモ化再帰で解く
static Dictionary<long, long> mMemoDict = new Dictionary<long, long>();
static long DFS(long pFrontInd, long pRearInd)
{
long Hash = pFrontInd * 10000 + pRearInd;
if (mMemoDict.ContainsKey(Hash)) {
return mMemoDict[Hash];
}
// 先手番か後手番かを求める
long DiffSum = pFrontInd + (UB - pRearInd);
bool IsSente = (DiffSum % 2 == 0);
if (pFrontInd > pRearInd) {
return 0;
}
var SeniList = new List<long>();
// 先頭から取る場合
long Result1 = DFS(pFrontInd + 1, pRearInd);
if (IsSente) Result1 += mAArr[pFrontInd];
else Result1 -= mAArr[pFrontInd];
SeniList.Add(Result1);
// 末尾から取る場合
long Result2 = DFS(pFrontInd, pRearInd - 1);
if (IsSente) Result2 += mAArr[pRearInd];
else Result2 -= mAArr[pRearInd];
SeniList.Add(Result2);
if (IsSente) return mMemoDict[Hash] = SeniList.Max();
return mMemoDict[Hash] = SeniList.Min();
}
}
解説
先手の得点 - 後手の得点 をSとおいて
先手はSを最大化しようとして
後手はSを最小化しようとします。
後は、メモ化再帰で
先手は遷移可能な状態からSが最大の状態を選び
後手は遷移可能な状態からSが最小の状態を選ぶ
ようにします。
類題