2019年10月14日月曜日

KUPC 2019 D - Maximin Game

KUPC 2019 D - Maximin Game

とりあえずDPっぽいものから考えた。カード11から順にカードNNまで二人に配っていくとして、千咲さんにxx枚、月乃瀬さんにyy枚配った時点で、条件に合っているような配り方の総数をdp[x][y]dp[x][y]とする。遷移としては

(Sx=1(S_x=1かつxy)x\le y)または(Sx=0(S_x = 0かつx>y)x > y)なら

dp[x][y]+=dp[x1][y]dp[x][y] += dp[x-1][y]

(Sy=0(S_y=0かつyx)y \le x)または(Sy=1(S_y = 1かつy>x)y > x)なら

dp[x][y]+=dp[x][y1]dp[x][y] += dp[x][y-1]

で求まるが、O(N2){\mathcal O}(N^2)なので制約的に無理だし、実はメモ化再帰で枝刈りされるみたいなこともないし、うまい高速化も思いつかないし……となって困っていた。

こういう問題の言い換えとして、原点OOからスタートして千咲さんがカードを取ったらベクトル(1,1)(1, 1)に沿って進み、月乃瀬さんが取ったらベクトル(1,1)(1, -1)に沿って進むというのがあったなと思い出して実験してみると、次のような性質が見える:

  • OOからスタートして(2N,0)(2N, 0)に着く
  • yy座標が正の時は月乃瀬さんが勝っていて、yy座標が負の時は千咲さんが勝っている。つまり、文字列SSで勝ち負けが切り替わるところでxx軸と交わる。

すなわち、SS中で00が連続している部分ではxx軸の上にいなければならず(xx軸を踏んでも良い)、11が連続している部分では下にいなければならない。このパスの数え上げは有名なのがあった気がすると思ってググったらカタラン数だった。同じ要素が連続している各部分列についてカタラン数を求めてかけ合わせれば答えになっている。