AtCoderのARC
次のARCの問題へ
前のARCの問題へ
ARC122-B Insurance
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");
WillReturn.Add("3 1 4");
//1.83333333333333333333
}
else if (InputPattern == "Input2") {
WillReturn.Add("10");
WillReturn.Add("866111664 178537096 844917655 218662351 383133839 231371336 353498483 865935868 472381277 579910117");
//362925658.10000000000000000000
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static double[] mAArr;
static void Main()
{
List<string> InputList = GetInputList();
mAArr = InputList[1].Split(' ').Select(pX => double.Parse(pX)).ToArray();
double Result = ExecSanbuntansaku();
Console.WriteLine(Result);
}
// 三分探索で極小値を求める
static double ExecSanbuntansaku()
{
double L = 0;
double R = mAArr.Max();
var PairHashSet = new HashSet<string>();
while (L + double.Epsilon < R) {
double C1 = (L * 2 + R) / 3;
double C2 = (L + R * 2) / 3;
double C1Val = DeriveY(C1);
double C2Val = DeriveY(C2);
if (C1Val < C2Val) {
R = C2;
}
else {
L = C1;
}
string Hash = string.Format("{0},{1}", L, R);
if (PairHashSet.Add(Hash) == false) {
break;
}
}
var MinKouhoList = new List<double>();
MinKouhoList.Add(DeriveY(L));
MinKouhoList.Add(DeriveY(R));
return MinKouhoList.Min();
}
// Xの値を引数として、期待値を返す
static double DeriveY(double pX)
{
double WillReturn = 0;
foreach (double EachA in mAArr) {
WillReturn += pX + EachA - Math.Min(EachA, pX * 2);
}
WillReturn /= mAArr.Length;
return WillReturn;
}
}
解説
下に凸なグラフなので三分探索してます。