AtCoderのARC
次のARCの問題へ
前のARCの問題へ
ARC137-B Count 1's
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");
WillReturn.Add("0 1 1 0");
//4
}
else if (InputPattern == "Input2") {
WillReturn.Add("5");
WillReturn.Add("0 0 0 0 0");
//6
}
else if (InputPattern == "Input3") {
WillReturn.Add("6");
WillReturn.Add("0 1 0 1 0 1");
//3
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static int UB;
static void Main()
{
List<string> InputList = GetInputList();
int[] AArr = InputList[1].Split(' ').Select(pX => int.Parse(pX)).ToArray();
UB = AArr.GetUpperBound(0);
int MaxOneCnt = ExecDP(AArr);
var ChangeList = new List<int>();
foreach (int EachA in AArr) {
if (EachA == 0) ChangeList.Add(1);
if (EachA == 1) ChangeList.Add(0);
}
int MaxZeroCnt = ExecDP(ChangeList.ToArray());
int MinOneCnt = AArr.Length - MaxZeroCnt;
Console.WriteLine(MaxOneCnt - MinOneCnt + 1);
}
// 1を最大で何個にできるかを返す
static int ExecDP(int[] pAArr)
{
int DefaultCnt = pAArr.Count(pX => pX == 1);
// 最大スコア[区間End] なDP表
int[] DPArr = new int[UB + 1];
for (int I = 0; I <= UB; I++) {
// 貰うDP
var KouhoList = new List<int>();
if (pAArr[I] == 0) {
KouhoList.Add(1);
}
else {
KouhoList.Add(-1);
}
int PrevInd = I - 1;
if (PrevInd >= 0) {
if (pAArr[I] == 0) {
KouhoList.Add(DPArr[I - 1] + 1);
}
else {
KouhoList.Add(DPArr[I - 1] - 1);
}
}
DPArr[I] = KouhoList.Max();
}
return Math.Max(DefaultCnt, DefaultCnt + DPArr.Max());
}
}
解説
PPPMMPPPMMMMMMMPPPPMM
という文字列でPの数が、基準スコアとし、
自由に区間を選んで
Pは1点、Mは-1点として
スコアを変化させれる時の、最大スコアは、
最大スコア[区間End]
を貰うDPで更新して、求めることができます。
そして、スコアは1点刻みで変化するので
最低スコアから最大スコアまでの、スコアは、全て達成可能です。