AtCoderのARC
次のARCの問題へ
前のARCの問題へ
ARC042-C おやつ
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("4 100");
WillReturn.Add("30 50");
WillReturn.Add("40 40");
WillReturn.Add("50 100");
WillReturn.Add("60 80");
//190
}
else if (InputPattern == "Input2") {
WillReturn.Add("5 100");
WillReturn.Add("40 10");
WillReturn.Add("30 50");
WillReturn.Add("60 80");
WillReturn.Add("20 40");
WillReturn.Add("20 70");
//200
}
else if (InputPattern == "Input3") {
WillReturn.Add("10 654");
WillReturn.Add("76 54");
WillReturn.Add("62 19");
WillReturn.Add("8 5");
WillReturn.Add("29 75");
WillReturn.Add("28 4");
WillReturn.Add("76 16");
WillReturn.Add("96 24");
WillReturn.Add("79 30");
WillReturn.Add("20 64");
WillReturn.Add("23 56");
//347
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
struct ItemDef
{
internal long Omosa;
internal long Val;
}
static List<ItemDef> mItemList = new List<ItemDef>();
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 OmosaLimit = wkArr[1];
foreach (string EachStr in InputList.Skip(1)) {
SplitAct(EachStr);
ItemDef WillAdd;
WillAdd.Omosa = wkArr[0];
WillAdd.Val = wkArr[1];
mItemList.Add(WillAdd);
}
// 重さの降順にソート
mItemList = mItemList.OrderByDescending(pX => pX.Omosa).ToList();
// 価値合計[重さ]なDP表
var PrevDP = new Dictionary<long, long>();
PrevDP[0] = 0;
long Answer = long.MinValue;
foreach (ItemDef EachItem in mItemList) {
var CurrDP = new Dictionary<long, long>(PrevDP);
foreach (var EachPair in PrevDP) {
long NewKey = EachPair.Key + EachItem.Omosa;
long NewVal = EachPair.Value + EachItem.Val;
Answer = Math.Max(Answer, NewVal);
if (NewKey > OmosaLimit) {
continue;
}
if (CurrDP.ContainsKey(NewKey)) {
if (CurrDP[NewKey] > NewVal) {
continue;
}
}
CurrDP[NewKey] = NewVal;
}
PrevDP = CurrDP;
}
Console.WriteLine(Answer);
}
}
解説
上限が100円で
おやつの価格が
30円,40円,50円で考察すると、
最終形は、集合の最小値以外の和が100以下であると分かります、
なので、重さの降順に、
価値合計[重さ]を更新するDPで
計算量、O(N*N)で解くことができます。