ABC 011 D - 大ジャンプ
以下、X,Yは最初からDで割ったものを扱い、D=1とする。x軸に沿ってk+回+1進み、k−回−1進み、y軸に沿ってl+回+1進み、l−回−1進む場合を考える。このように進む確率をP(k+,k−,l+,l−)とすると、
P(k+,k−,l+,l−)=(k+N)(k−N−k+)(l+N−k+−k−)4−N
である。あとは(X,Y)にたどりつくようなk+,k−,l+,l−の組み合わせについてPを足し合わせればよい。具体的には、k+が与えられたとき、k+−k−=X, l+−l−=Y, k++k−+l++l−=Nより、残りは以下のように定まる。
k−l+l−===k+−X21(N−k+−k−+Y)21(N−k+−k−−Y)
したがって、各k+∈{0,1,...,N}について(k−, l+, l−が有効な値なら)P(k+,k−,l+,l−)を足し合わせると、それが答えになる。
しかし、上のPをそのまま計算すると倍精度ではオーバーフローしてしまうので、logを経由することにする:
P(k+,k−,l+,l−)=exp(log(k+N)+log(k−N−k+)+log(l+N−k+−k−)−Nlog4)
log(mn)=logn!−logm!−log(n−m)!だから、階乗の対数が求まればよい。今回はNが小さいので素朴に足すだけでも問題ないし、大きい場合も精度のよい漸近公式がいろいろある。
想定解法ではなさそうと思いながら書いた。対数を取る方法は、ABC 094 - Dがわからなくて苦し紛れに書いたのをコピペしただけなのだが、(精度的な意味で)どのくらい頑健なのかよくわかっていない。
想定解法は、最初から確率で遷移することで、値が大きくならないようにするというものだった。パスカルの三角形の(mn)/2nバージョンは頭に入れておいたほうが良さそう。