問題へのリンク
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 8");
WillReturn.Add("4 3 2");
WillReturn.Add("2 1 1");
WillReturn.Add("1 2 4");
WillReturn.Add("3 2 2");
//12
}
else if (InputPattern == "Input2") {
WillReturn.Add("2 100");
WillReturn.Add("1 1 100");
WillReturn.Add("2 1 50");
//150
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
struct ItemInfoDef
{
internal long Value;
internal long Weight;
}
static List<ItemInfoDef> mItemInfoList = new List<ItemInfoDef>();
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 WeightLimit = wkArr[1];
foreach (string EachStr in InputList.Skip(1)) {
SplitAct(EachStr);
long Value = wkArr[0];
long Weight = wkArr[1];
long Cnt = wkArr[2];
var Beki2List = new List<long>();
while (Cnt > 0) {
var ResultBeki2List = DeriveBeki2List(ref Cnt);
Beki2List.AddRange(ResultBeki2List);
}
foreach (long EachCnt in Beki2List) {
ItemInfoDef WillAdd;
WillAdd.Value = Value * EachCnt;
WillAdd.Weight = Weight * EachCnt;
mItemInfoList.Add(WillAdd);
}
}
// 最大価値[重さ合計]なインラインDP表
long UB = WeightLimit;
long?[] DPArr = new long?[UB + 1];
DPArr[0] = 0;
foreach (ItemInfoDef EachItem in mItemInfoList) {
for (long I = UB; 0 <= I; I--) {
if (DPArr[I].HasValue == false) continue;
long NewI = I + EachItem.Weight;
if (NewI > UB) continue;
long NewVal = DPArr[I].Value + EachItem.Value;
if (DPArr[NewI].HasValue) {
if (DPArr[NewI].Value >= NewVal) {
continue;
}
}
DPArr[NewI] = NewVal;
}
}
Console.WriteLine(DPArr.Max());
}
static List<long> DeriveBeki2List(ref long pVal)
{
var Beki2List = new List<long>();
long Beki2 = 1;
while (true) {
if (pVal < Beki2) break;
Beki2List.Add(Beki2);
pVal -= Beki2;
Beki2 *= 2;
}
return Beki2List;
}
}
下記のように、ダブリングの考え方を使用してます。 品物が100個使える場合 1+2+4+8+16+32 = 63 100 - 63 = 37 1+2+4+8+16 = 31 37 - 31 = 6 1+2 = 3 6 - 3 = 3 1+2 = 3 で、1,2,4,8,16,32,1,2,4,8,16,1,2,1,2 ずつ使用できるとして、 DPの遷移回数を減らしてます。