mini notes

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

ARC036 C - 偶然ジェネレータ

問題:C - 偶然ジェネレータ

解答:Submission #15324937 - AtCoder Regular Contest 036

解法:作成された文字列について前から文字を見てゆき、1なら+1、0なら-1する変数xを準備する。max(x) - min(x)がK以下ならその文字列は採用される。

このような文字列の個数は次のようなDPで計算できる。
dp[i][j][l] :i番目までの文字までみて、xの最大値がj、-xの最大値がlであるときの文字列の個数
遷移が肝である。配るDPで考える。
i番目の文字列が1である場合は、dp[i][j][l] ⇒ dp[i+1][j+1][max(l - 1, 0)] に遷移する。
i番目の文字列が0である場合は、dp[i][j][l] ⇒ dp[i+1][max(j-1, 0)][l+1] に遷移する。
i番目の文字列が?である場合は、上記のどちらにも遷移する。

どうしてこれでうまくいくのか、あまり理解していない…
実際に遷移を確認すると、j + l がmax(x) - min(x)になることが確認できる。