AtCoderのABC    次のABCの問題へ    前のABCの問題へ

ABC225-F String Cards


問題へのリンク


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 3");
            WillReturn.Add("ode");
            WillReturn.Add("zaaa");
            WillReturn.Add("r");
            WillReturn.Add("atc");
            //atcoder
        }
        else if (InputPattern == "Input2") {
            WillReturn.Add("5 2");
            WillReturn.Add("z");
            WillReturn.Add("z");
            WillReturn.Add("zzz");
            WillReturn.Add("z");
            WillReturn.Add("zzzzzz");
            //zz
        }
        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(pX => int.Parse(pX)).ToArray();
        int K = wkArr[1];

        var StringList = InputList.Skip(1).ToList();

        string Result = Solve(K, StringList);
        Console.WriteLine(Result);
    }

    // TakeCntとStringの配列を引数として、辞書順最小な文字列を返す
    static string Solve(int pTakeCnt, List<string> pStringList)
    {
        // S + Tでソートする
        pStringList.Sort((A, B) => (B + A).CompareTo(A + B));

        // 最小の文字列[使用した文字列の数]なDP表
        var PrevDP = new Dictionary<int, string>();
        PrevDP[0] = "";

        for (int I = 0; I <= pStringList.Count - 1; I++) {
            var CurrDP = new Dictionary<int, string>(PrevDP);
            foreach (var EachPair in PrevDP) {
                int NewKey = EachPair.Key + 1;
                if (NewKey > pTakeCnt) continue;

                string NewStr = pStringList[I] + EachPair.Value;
                if (CurrDP.ContainsKey(NewKey)) {
                    if (CurrDP[NewKey].CompareTo(NewStr) <= 0) {
                        continue;
                    }
                }
                CurrDP[NewKey] = NewStr;
            }
            PrevDP = CurrDP;
        }
        return PrevDP[pTakeCnt];
    }
}


解説

S + T でソートしてから、
最小の文字列[使用した文字列の数]
を文字列の後ろから決めていくDPで、解くことができます。