AtCoderのABC
次のABCの問題へ
前のABCの問題へ
ABC018-D バレンタインデー
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 4 2 3 7");
WillReturn.Add("1 1 9");
WillReturn.Add("1 2 7");
WillReturn.Add("1 3 15");
WillReturn.Add("1 4 6");
WillReturn.Add("2 2 3");
WillReturn.Add("2 4 6");
WillReturn.Add("3 3 6");
//37
}
else if (InputPattern == "Input2") {
WillReturn.Add("4 5 3 2 9");
WillReturn.Add("2 3 5");
WillReturn.Add("3 1 4");
WillReturn.Add("2 2 2");
WillReturn.Add("4 1 9");
WillReturn.Add("3 5 3");
WillReturn.Add("3 3 8");
WillReturn.Add("1 4 5");
WillReturn.Add("1 5 7");
WillReturn.Add("2 4 8");
//26
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
struct XYZInfoDef
{
internal int X;
internal int Y;
internal int Z;
}
static void Main()
{
List<string> InputList = GetInputList();
int[] wkArr = { };
Action<string> SplitAct = pStr =>
wkArr = pStr.Split(' ').Select(pX => int.Parse(pX)).ToArray();
SplitAct(InputList[0]);
int N = wkArr[0];
int M = wkArr[1];
int P = wkArr[2];
int Q = wkArr[3];
var XYZInfoList = new List<XYZInfoDef>();
foreach (string EachStr in InputList.Skip(1)) {
SplitAct(EachStr);
XYZInfoDef WillAdd;
WillAdd.X = wkArr[0];
WillAdd.Y = wkArr[1];
WillAdd.Z = wkArr[2];
XYZInfoList.Add(WillAdd);
}
// 女子N人からP人の選び方を全探索
List<HashSet<int>> SelectedSetList = ExecDFS(N, P);
int Answer = int.MinValue;
foreach (HashSet<int> EachSelectedSet in SelectedSetList) {
var tmp1 = XYZInfoList.FindAll(pX => EachSelectedSet.Contains(pX.X));
var tmp2 = tmp1.GroupBy(pX => pX.Y);
var tmp3 = tmp2.Select(pX => pX.Sum(pY => pY.Z));
var tmp4 = tmp3.OrderByDescending(pX => pX);
var tmp5 = tmp4.Take(Q).Sum();
Answer = Math.Max(Answer, tmp5);
}
Console.WriteLine(Answer);
}
struct JyoutaiDef
{
internal int CurrVal;
internal HashSet<int> SelectedSet;
}
// 女子N人からP人の選び方を全探索
static List<HashSet<int>> ExecDFS(int pN, int pP)
{
var WillReturn = new List<HashSet<int>>();
var Stk = new Stack<JyoutaiDef>();
JyoutaiDef WillPush;
WillPush.CurrVal = 1;
WillPush.SelectedSet = new HashSet<int>();
Stk.Push(WillPush);
while (Stk.Count > 0) {
JyoutaiDef Popped = Stk.Pop();
// クリア判定
if (Popped.SelectedSet.Count == pP) {
WillReturn.Add(Popped.SelectedSet);
continue;
}
for (int I = Popped.CurrVal; I <= pN; I++) {
WillPush.CurrVal = I + 1;
WillPush.SelectedSet = new HashSet<int>(Popped.SelectedSet);
WillPush.SelectedSet.Add(I);
Stk.Push(WillPush);
}
}
return WillReturn;
}
}
解説
半分全探索で解いてます。