AtCoderのABC
次のABCの問題へ
前のABCの問題へ
ABC350-E Toward 0
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("3 2 10 20");
//20.000000000000000
}
else if (InputPattern == "Input2") {
WillReturn.Add("3 2 20 20");
//32.000000000000000
}
else if (InputPattern == "Input3") {
WillReturn.Add("314159265358979323 4 223606797 173205080");
//6418410657.7408381
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static long mA;
static long mX;
static long mY;
static void Main()
{
List<string> InputList = GetInputList();
long[] wkArr = InputList[0].Split(' ').Select(pX => long.Parse(pX)).ToArray();
long CurrVal = wkArr[0];
mA = wkArr[1];
mX = wkArr[2];
mY = wkArr[3];
decimal Result = DFS(CurrVal);
Console.WriteLine(Result);
}
// 現在値を引数として、残り金額の期待値を返す
static Dictionary<long, decimal> mMemo = new Dictionary<long, decimal>();
static decimal DFS(long CurrVal)
{
if (mMemo.ContainsKey(CurrVal)) {
return mMemo[CurrVal];
}
if (CurrVal == 0) return 0;
var KouhoList = new List<decimal>();
// X円払う場合
KouhoList.Add(mX + DFS(CurrVal / mA));
// Y円払う場合
// 当たりを引くまでの期待値
decimal Ex1 = 0;
Ex1 += mY * 6M / 5M;
decimal Ex2 = 0;
for (long I = 2; I <= 6; I++) {
Ex2 += 1M / 5M * DFS(CurrVal / I);
}
decimal NewEx = Ex1 + Ex2;
KouhoList.Add(NewEx);
return mMemo[CurrVal] = KouhoList.Min();
}
}
解説
メモ化再帰で解いてます。