mini notes

競技プログラミングの解法メモを残していきます。

ABC011 D - 大ジャンプ

問題:D - 大ジャンプ

解答:(100点解法)Submission #11654098 - AtCoder Beginner Contest 011
(101点解法)Submission #11681204 - AtCoder Beginner Contest 011

解法:d | xかつd | y でないと到達不可能。よってx' = x / d, y' = x / d , d' = 1とし、以降x, y, dをx', y', d'で置き換えて問題を考える。

abs(x) + abs(y) > N なら到達不可能。また、(abs(x) + abs(y)) % 2 != N % 2でも到達不可能。これ以外の場合は到達可能。

N ≦ 30までならメモ化再帰で算出可能。30 < N ≦ 1000を考える。

ジャンプのうち左右ジャンプの回数をlr回とすると、上下ジャンプはn - lr回となる。この時、左ジャンプをl回とすると右ジャンプはlr - l回であり、lr - l - l = x より、l = (lr - x) / 2である。同様に、上ジャンプをu回とするとしたジャンプはn - lr - u回であり、n - lr - u - u = yより、u = (n - lr- y) / 2である。よって、左右ジャンプの回数lrが決まるとx, yの設定により上下左右ジャンプの回数がすべて決まるため、その確率を加算すればよい。(ソースコードでは左右と上下をそれぞれ逆に計算している。xを-x、yを-yと読み替えれば上記説明が当てはまる)

左右ジャンプの回数をlrとするとき、(x, y)に到達する確率は、denom[n] = 22 * n , comb[x][y] = xCyとするとき、

comb[n][lr] * comb[lr][(lr - x) / 2] * comb[n- lr][(n - lr- y) / 2] / denom[n]

となる。ただしdenom[n]の最大値の22000はdouble型でオーバーフローするため、comb[n][lr] / denom[n], comb[lr][(lr - x) / 2] / denom[lr], comb[n - lr][(n - lr - y)] / denom[n - lr]をそれぞれ計算し、それを掛け合わせるとよさそう。