問題
$ N $ 個の文字列 $ s_0, s_1, …, s_{N-1} $ が与えられます。
これらの文字列を好きな順序で並べた後、連結して1つの文字列を作ります。
作った文字列に“AB”が最大で何個含まれるかを求めて下さい。
[条件]
🔹文字列の数 $ N $ は $ 1 $ 以上 $ 10^4 $ 以下の整数
🔹$ s_i $ は英大文字
🔹$ s_i $ の長さは $ 2 $ 以上 $ 10 $ 以下
解法・ソースコード
この問題は連結部の“AB”の個数を最大化する問題と言えます。
$ N $ 個の文字列 $ s_0, s_1, …, s_{N-1} $ は次の4パターンに分類できます。
🔹パターン1:B***A(左端が”B”で、右端が”A”)
🔹パターン2:****A(左端が”B”ではなく、右端が”A”)
🔹パターン3:B****(左端が”B”で、右端が”A”ではない)
🔹パターン4:*****(左端が”B”ではなく、右端も”A”ではない)
パターン4はほかの文字列と連結して“AB”となることはないので無視します。
パターン1、2、3の個数をそれぞれ $ c_1, c_2, c_3 $ とします。
「理論的にこれより多く作るのは不可能である」という上界を考えます。
“A”の個数は全部で $ c_1 + c_2 $ 個であり、“B”の個数は全部で $ c_1 + c_3 $ 個です。
したがって、$ min(c_1 + c_2, c_1 + c_3) = c_1 + min(c_2, c_3) $ よりも多くの“AB”を作ることは絶対できません。
$ c_2 = c_3 = 0 $ の場合、パターン1同士が連結した部分でしか “AB”をつくれませんので、答えは $ max(c_1 - 1, 0) $ となります。
また、$ c_2 $ と $ c_3 $ のうち少なくとも一方が $ 1 $ 以上である場合には、$ c_1 + min(c_2, c_3) $ 個の“AB”を作ることができます。
上記を踏まえると以下の手順で問題を解くことができます。
🔹各文字列 $ s_0, s_1, …, s_N-1 $ にすでに含まれている“AB”の個数の総和を $ T $ とする。
🔹各文字列を4パターンに分類する。( $ c_1,c_2,c_3 $ の定義は前述の通り)
🔹$ c_2 = c_3 = 0 $ の場合、$ T + max(c_1 - 1, 0) $ 個の“AB”ができる。
🔹$ c_2 $ と $ c_3 $ いずれかが $ 1 $ 以上の場合、$ T + c_1 + min(c_2, c_3) $ 個の“AB”ができる。
[Google Colaboratory]
1 | #--------- 入力例 ----------- |
[実行結果]
2
“ABCA”、”BAD”、”XBAZ”の順に結合して、”ABCABADXBAZ”を作ると、“AB”が2つできることが確認できます。