ツバサの備忘録

主に備忘録代わりに精進記録を載せていくつもりです。

ABC113 D - Number of Amidakuji

問題
提出コード
DPをします。
まずは、下準備をします。
ある高さについて、幅がxのとき(つまり、x+1本の棒があるとき)に、横線の置き方がいくつあるかを計算します。
これをmemo[x]とします。 x=0のとき、横線はおけないのでmemo[0]=0です。
x=1のとき、横線を置くか置かないかの2通りです。よってmemo[1]=2です。
x=2のときについて考えます。
横線を置くと1、置かないと0とすると、
00,01,10の3通りです。
memo[2]=3です。
これ以降については、実はフィボナッチ数列のようになっています。
幅がxのとき、一番右側に横線を置くか置かないかで場合分けをします。

  • 横線を置かないとき
    一番右端を除く、x-1の幅についての置き方を考えればよいので、これは
    memo[x-1]になります。

  • 横線を置くとき
    一番右端に横線を置くと、その左側は自動的に横線を置くことができなくなります。
    残ったx-2の幅については自由に置くことができるので、これは
    memo[x-2]になります。

ということで、
memo[x] = memo[x-1]+memo[x-2]
となります。
Wの最大値が8なので、これは手計算で求めてもいいですし、プログラムを書いてO(W)で求めてもいいと思います。

さて、答えの数え上げをしていきます。
dp[i][j]=一番上の高さのときに、一番左の棒からスタートしたときに、上からi番目の高さにいるときに、左からj番目にたどり着くようなものの個数
とします(jは0-indexedとします)。初期状態は、dp[0][0]=1です。
すると、
i-1のときに、j-1jj+1の3つのどこかにいる必要があります。
それぞれ、i-1のときに、左上、真上、右上にいて、そこから横線を通り(または通らず)、今の場所に移動します。

  • 左(右)上から移動してくる場合
    考えることは同じなので、今回は左上から移動する場合についてのみ考えます。
    j番目の棒線にたどり着くとき、j-1j区間に横線を引くため、jj+1およびj-2j-1区間には、横線があってはいけません。
    ですが、それ以外の部分は自由に横線をひくことができます。
    この部分は、jより左側と右側に分割することができ、幅がそれぞれ
    w-1-(j+1)j-2になります。
    ということで、この二つの幅についての横線の置き方は、memoを参照することで求められます。
    あとは、その二つとdp[i-1][j-1]を掛け算すればよいので、
    memo[w-1-(j+1)]×memo[j-2]×dp[i-1][j-1]
    となります。
    同様にすると、右上から移動するパターンは
    memo[w-1-(j+2)]×memo[j-1]×dp[i-1][j+1]
    となります。

  • 移動せずに降りてくる場合
    jの左右には横線があってはいけません。しかし、それ以外は横線を自由に置くことができます。ということで、次のようになります。
    memo[w-1-(j+1)]×memo[j-1]×dp[i-1][j]


ということで、この3つの式の和がdp[i][j]の値になります。
これを計算していくと、答えがdp[h][k-1]にあります。