Official

C - Grid Coloring 3 Editorial by leaf1415


時系列を逆向きに考え、最後の操作から順に決定することにより、問題文中の操作は下記の操作に置き換えられます。

操作の中心となるマスを選択し、中心と同じ行または列にある(中心自身も含む)全ての無色のマスを任意の一色で塗る。

\(1\) 回目の操作は、中心と同じ行または列にある十字形の部分を一色で塗る操作になります。 \(2\) 回目以降の操作は、\(1\) 回目の操作で塗った十字形内のマスを中心として操作を行うことで、実質的に下記の \(2\) 種類の操作が可能であり、かつ、この \(2\) 種類のみを考えれば十分です。

  • 無色のマスを含むある一行を選び、その行にある全ての無色マスを任意の一色で塗る。
  • 無色のマスを含むある一列を選び、その列にある全ての無色マスを任意の一色で塗る。

上記の操作で実現できる、全マスに色が塗られたグリッドにおける各マスの色の組合せ(以下、と呼ぶ)を数え上げるにあたっては、 複数の異なる手順から同一の絵が作られ得るため、 単純に可能な手順の個数を数え上げるのでは同じ絵を重複して数えてしまいます。 例えば、手順中に行を塗る操作が複数個連続するとき、それらの順番を入れ替えたとしても(あるいはそれらを同時に行うとみなしても)同じ結果をもたらします。

その対策として、それぞれの絵 \(P\) に対し、\(P\) を作る標準的な手順を下記で定めます。

  • 下記の行同時操作列同時操作\(1\) 回ずつ交互に繰り返す。すなわち、\(P\) が完成するまで、( \(1\) 回目の行同時操作 \(R_1\)\(\to\)\(1\) 回目の列同時操作 \(C_1\)\(\to\)\(2\) 回目の行同時操作 \(R_2\)\(\to \cdots\) と繰り返す。

    • 行同時操作:\(1\) 個以上の行を選び、それぞれを任意の一色で同時に塗る(塗る色は行ごとに異なっても良い)。
    • 列同時操作:\(1\) 個以上の列を選び、それぞれを任意の一色で同時に塗る(塗る色は列ごとに異なっても良い)。
  • \(R_i, C_i\) では、\(P\) を作る上でその時点で可能な限り多くの行(または列)を選択して塗る。

実現可能な絵それぞれに対して、それを作るための標準的な手順が唯一に定まるため、本問題を解くためには標準的な手順として有効なものを数え上げれば良いです。

そのためには、各 \(R_i, C_i\) で塗る行・列の集合およびそれらを塗るのに使用する色の組合せであって、下記の制約を満たすものの個数を数え上げれば良いです。

  • まず、「 \(1\) 回目の操作は、中心と同じ行または列にある十字形の部分を一色で塗る」ことに対応して下記を満たす:

    • \(R_1\) では選択した全ての行を同一の色で塗る。
    • \(C_1\) で塗る列のうち少なくとも一つは \(R_1\) で使用した色で塗る。
  • また「その時点で可能な限り多くの行(または列)を選択して塗る」ことに対応して、任意の \(i \geq 1\) で下記を満たす:

    • \(C_i\) で全ての行を同一の色で塗った場合、\(R_{i+1}\) ではその色は使用しない。(もし \(R_{i+1}\) で、ある行を \(C_i\) で使用した色で塗るのであれば、その行は \(R_i\) の時点で塗ることが可能であったことになり矛盾します。)
    • \(R_{i+1}\) で全ての行を同一の色で塗った場合、\(C_{i+1}\) ではその色は使用しない。
    • \(R_1\) を除いて、\(1\) 回の同時操作で残りの全てのマスを塗る場合は「それら全てを同一の色で塗る」ことはしない。(もし全てのマスを同一の色で塗って絵が完成するのであれば、直前の同時操作で全てのマスを塗って絵を完成することが可能であったことになり矛盾します。)

上記の制約を満たす手順を動的計画法によって数え上げます。 具体的には、無色マスが残っている行数・列数と、次の同時操作で使用可能な色に制約があるかを示すフラグなどを key にした 状態数 \(O(N^2)\) の DP テーブル(ただし、\(N \coloneqq \max \lbrace H, W \rbrace\) )を用い、各状態から次の同時操作で色を塗る行数(または列数)それぞれに対応した \(O(N)\) 通りの遷移を行うことで、全体で \(O(N^3)\) 時間で本問題を解くことができます。

posted:
last update: