競プロ典型 90 問 002 valid parens の列挙
競プロ典型 90 問 002 の解説のうち、 ngtkana さんのもので紹介されている方法がうまくいく理由を次のように考えた。
以下のことを確かめる。
- 操作後の列は正しいカッコ列である
- 辞書順で操作前と操作後の間に正しいカッコ列は無い
お断り
"("と")"からなる列が正しいカッコ列であることと次のことは同値:
とする。列の左から1文字ずつ読み取り、"("ならば+1、")"ならば-1をに足す。以下の両方が成り立つ。
- 最後の文字を読み終えた時点で
- 最後の文字を読み終えるまで常に
上に出てきたをスコアと呼んだり、の文字目を読み終えた時点のの値を指してと書いたりさせてもらう。 また、列が明らかな場面では下付き文字を省略して単にと書かせてもらう
1.を確かめる
操作の前後で"("と")"の個数は変わらないから、操作前が正しいカッコ列ならば操作後の列も先述の(a)を満たす。
以下、操作後の列が先述の(b)も満たすことを確かめる。
操作前の列で最も右にある"())"の"("の位置を左から文字目と呼ぶことにする。
操作後の列を左から文字目まで、文字目、文字目から終わりまでの三つの部分に分けてスコアが0以上となっていることを確認する。
一つ目の部分
操作前後で左から文字目までは等しいから操作後の列の左から文字目まではスコアが0以上である。
二つ目の部分
操作前の列は先述の(b)を満たすことと、文字目が"())"という並びであることからである。
操作後の列の文字目は")"になっているが、が成り立つ。
三つ目の部分
操作後の列のから終わりまでは"("を左、")"を右に寄せた形である。
"("が連続する間は明らかにスコアが0以上である。
")"が連続する間にスコアが0より小さくなると仮定する。
このとき、の文字目から終わりまでの形からしてとなる。
一方、操作の前後で"("と")"の個数は変わらないからとなるべきで、矛盾がある。
背理法から")"が連続する間にスコアが0より小さくなることはない
2.を確かめる
操作後の列が、文字目が")"な列の中では、辞書順で最も早いことは文字目から終わりまでの形から明らかであり、正しいカッコ列でもある。
後は次のすべてを満たす列がないことがわかればよい:
- より遅い
- 文字目までと等しい
- 正しいカッコ列
(i)と(ii)の二つを満たす列は(iii)を満たさないことを確認する。
(i)をまじめに言い直すと、で , , を満たすものが存在する。ここでなどは列の文字目を表す。
(ii)より
ところでについて最も右の"())"より右にある"("ではスコアが1になる。まじめに書くと次が成り立つ:
かつならば
なぜならばとすると、最後の文字を読み終えた時点でスコアが0になるには文字目より右で")"が2個以上連続しなければならない。
文字目より右で")"が2個以上連続すると、文字目の"())"より右にさらに"())"があることとなり、矛盾する。
背理法から
"("を読んでスコアが1になるなら、その一文字前ではスコアは0である。
以上をまとめるととなり、を左から読むと文字目でスコアは負となるからは正しいカッコ列でない