AtCoderのABC
次のABCの問題へ
前のABCの問題へ
ABC116-D Various Sushi
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("5 3");
WillReturn.Add("1 9");
WillReturn.Add("1 7");
WillReturn.Add("2 6");
WillReturn.Add("2 5");
WillReturn.Add("3 1");
//26
}
else if (InputPattern == "Input2") {
WillReturn.Add("7 4");
WillReturn.Add("1 1");
WillReturn.Add("2 1");
WillReturn.Add("3 1");
WillReturn.Add("4 6");
WillReturn.Add("4 5");
WillReturn.Add("4 5");
WillReturn.Add("4 5");
//25
}
else if (InputPattern == "Input3") {
WillReturn.Add("6 5");
WillReturn.Add("5 1000000000");
WillReturn.Add("2 990000000");
WillReturn.Add("3 980000000");
WillReturn.Add("6 970000000");
WillReturn.Add("6 960000000");
WillReturn.Add("4 950000000");
//4900000016
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
struct TDInfoDef
{
internal long T;
internal long D;
}
static void Main()
{
List<string> InputList = GetInputList();
long[] wkArr = { };
Action<string> SplitAct = pStr =>
wkArr = pStr.Split(' ').Select(pX => long.Parse(pX)).ToArray();
SplitAct(InputList[0]);
long K = wkArr[1];
var TDInfoList = new List<TDInfoDef>();
foreach (string EachStr in InputList.Skip(1)) {
SplitAct(EachStr);
TDInfoDef WillAdd;
WillAdd.T = wkArr[0];
WillAdd.D = wkArr[1];
TDInfoList.Add(WillAdd);
}
var AppearTSet = new HashSet<long>();
var DList1 = new List<long>();
var DList2 = new List<long>();
foreach (TDInfoDef EachTDInfo in TDInfoList.OrderByDescending(pX => pX.D)) {
if (AppearTSet.Add(EachTDInfo.T)) {
DList1.Add(EachTDInfo.D);
}
else {
DList2.Add(EachTDInfo.D);
}
}
// 累積和を求めておく
long[] RunSum1 = DList1.ToArray();
long[] RunSum2 = DList2.ToArray();
for (int I = 1; I <= RunSum1.GetUpperBound(0); I++) {
RunSum1[I] += RunSum1[I - 1];
}
for (int I = 1; I <= RunSum2.GetUpperBound(0); I++) {
RunSum2[I] += RunSum2[I - 1];
}
long Answer = 0;
// 種類数で全探索
for (int I = 0; I <= Math.Min(K, RunSum1.Length); I++) {
long AnswerKouho = 0;
if (I > 0) {
AnswerKouho += RunSum1[I - 1];
}
long Rest = Math.Min(K - I, RunSum2.Length);
if (Rest > 0) {
AnswerKouho += RunSum2[Rest - 1];
}
// 2乗が種類ボーナスになる
AnswerKouho += (long)I * I;
Answer = Math.Max(Answer, AnswerKouho);
}
Console.WriteLine(Answer);
}
}
解説
種類ごとの最大の美味しさを持つList(美味しさの降順にAdd)
種類ごとの2番目以降の美味しさを持つList(美味しさの降順にAdd)
の2つのListを作り、
それぞれのListから何件取得するかを全部試してます。