AtCoderのPAST
次のPASTの問題へ
前のPASTの問題へ
第1回PAST G 組分け
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("6");
WillReturn.Add("10 10 -10 -10 -10");
WillReturn.Add("10 -10 -10 -10");
WillReturn.Add("-10 -10 -10");
WillReturn.Add("10 -10");
WillReturn.Add("-10");
//40
}
else if (InputPattern == "Input2") {
WillReturn.Add("3");
WillReturn.Add("1 1");
WillReturn.Add("1");
//3
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static void Main()
{
List<string> InputList = GetInputList();
int[] wkArr = InputList[0].Split(' ').Select(X => int.Parse(X)).ToArray();
int N = wkArr[0];
var ADict = new Dictionary<string, int>();
for (int I = 1; I <= N - 1; I++) {
wkArr = InputList[I].Split(' ').Select(X => int.Parse(X)).ToArray();
for (int J = 0; J <= wkArr.GetUpperBound(0); J++) {
string wkKey = string.Format("{0},{1}", I, I + 1 + J);
ADict[wkKey] = wkArr[J];
}
}
var GroupList = DeriveGroupList(N);
int MaxScore = int.MinValue;
foreach (JyoutaiDef EachGroup in GroupList) {
int Score = 0;
Action<List<int>> wkAct = (pList) =>
{
for (int I = 0; I <= pList.Count - 1; I++) {
for (int J = I + 1; J <= pList.Count - 1; J++) {
string wkKey = string.Format("{0},{1}", pList[I], pList[J]);
Score += ADict[wkKey];
}
}
};
wkAct(EachGroup.Group1);
wkAct(EachGroup.Group2);
wkAct(EachGroup.Group3);
if (MaxScore < Score) MaxScore = Score;
}
Console.WriteLine(MaxScore);
}
struct JyoutaiDef
{
internal int Level;
internal List<int> Group1;
internal List<int> Group2;
internal List<int> Group3;
}
// 3つ以下のグループに配置して返す
static List<JyoutaiDef> DeriveGroupList(int pN)
{
var WillReturn = new List<JyoutaiDef>();
JyoutaiDef WillPush;
WillPush.Level = 0;
WillPush.Group1 = new List<int>();
WillPush.Group2 = new List<int>();
WillPush.Group3 = new List<int>();
var Stk = new Stack<JyoutaiDef>();
Stk.Push(WillPush);
while (Stk.Count > 0) {
JyoutaiDef Popped = Stk.Pop();
if (Popped.Level == pN) {
WillReturn.Add(Popped);
continue;
}
WillPush.Level = Popped.Level + 1;
WillPush.Group1 = new List<int>(Popped.Group1) { Popped.Level + 1 };
WillPush.Group2 = Popped.Group2;
WillPush.Group3 = Popped.Group3;
Stk.Push(WillPush);
// 1人目は、必ずグループ1に配置する
if (Popped.Level == 1) continue;
WillPush.Group1 = Popped.Group1;
WillPush.Group2 = new List<int>(Popped.Group2) { Popped.Level + 1 };
WillPush.Group3 = Popped.Group3;
Stk.Push(WillPush);
WillPush.Group1 = Popped.Group1;
WillPush.Group2 = Popped.Group2;
WillPush.Group3 = new List<int>(Popped.Group3) { Popped.Level + 1 };
Stk.Push(WillPush);
}
return WillReturn;
}
}
解説
10人を最大で3グループに分けるので
場合の数は、3の9乗 = 19683 通り
ですので、DFSで全ての組合せを列挙してます。