CODEFESTIVAL QualB D問題
先週行われたCODEFESTIVAL 2017 QualB D問題 が解けなかったのですが、解説を読んでもちょっとわからなかったので、他の人のコードを見ながら自分なりに解法を考えていく過程を文章にしました。参考にしてくださる方がいたらうれしいです。
ちなみに私のコードはこちらです(お恥ずかしい)
Submission #1686548 - CODE FESTIVAL 2017 qual B | AtCoder
また今回の解答を考えるにあたっては、上級者の方のコードを参考にさせていただきましたが、Alex_2oo8 さんのコードが最も勉強になりました。感謝とともにクレジットいたします。
Submission #1666434 - CODE FESTIVAL 2017 qual B | AtCoder
問題文
1と0よりなる数列が与えられる。101 の並びを010 に変換することを繰り返すとき、最大何回この変換を行うことができるか? 制約などは各自元ページで確認してください。
D: 101 to 010 - CODE FESTIVAL 2017 qual B | AtCoder
解説
問題を相互に影響しない部分問題に分割する
101 → 010 をここではスコア化と呼ぼう。 2セル以上続く0で隔てられたセルの配列は、一方のスコア化によって他方の配列が影響を受けないので、スコア化の順序を考える際は2つの配列は独立した問題と考えて良い。したがって、まず2セル以上連続する0を用いてセル配列全体をsplit する。split されて得られたパターンの列を と表記する。
部分問題の分析
最初の状態でスコア化できるパターンはどこ?
split された部分配列の要素は0を連続して持たない。つまり、0の両隣は1となり、かならず”101”のパターンを持つ。これは”010”に変換して得点が得られるパターンである(スコア化可能パターンと呼ぶ)。
1が連続した配列に注目すると、スコア化のやりかたが整理できる
解説にもある通り、101111… (101{k})というパターンは、左端の101 をスコア化すると、010111… となり、ちょうどスコア化可能パターンが1つ右隣のセルにずれるようにして再び現れる。これを続けて0000…010 となるまで続けると、ちょうどk点を獲得することができる。これは左右を反転した…11101 (1{k}01)というパターンでも同様である。これを連続スコア化と呼ぶ。 いま、 を0 でsplit した配列を考える。得られた配列の要素は1が連続する配列(1-セグメントと呼ぶ)である。左からj番目の1-セグメントを、の配列の長さを要素とする配列を とし、いまi を固定し と考えて、単に と表記する。
いかなるスコア化も行っていない状態では、s 中の全ての1-セグメントの左端もしくは右端はかならずスコア化可能パターンになっており、を連続スコア化することによって 点を獲得することができる。
しかし、 は左端のスコア化可能パターンを と、右端のスコア化可能パターンを とそれぞれ共有しており、 がどのような方法でスコア化を行うかによって、 で可能なスコア化の手法が制限される。
スコア化のやりかたと、隣接する1-セグメントへの影響
いま を起点として考える。
のとき
- の左端のスコア化可能パターンをスコア化すると の右端のスコア化可能パターンは消失する。また、の’1’ を1つ消費するので、 が1減少する。
- そのままスコア化を続け、 回のスコア化を行うと、 の右端との境界は…1001… となり、 の左端のスコア化可能パターンも消失する。
- 回のスコア化を行うと、 の右端との境界は…0101… となり、 の左端のスコア化可能パターンは温存される。スコア化の回数は 回より少なくても のスコア化可能パターンの状態は変わらないので、 より少ない回数のスコア化のことは考えなくても良い。
- 上記1, 2 について左端を右端に、 を に置き換えても同様である。
- スコア化を行わない場合、両端のスコア化可能パターンが温存される。
のとき
- 左端のスコア化可能パターンをスコア化すると、常に右端のスコア化パターンも消失する。 が1減少する。
- 上記で左端を右端に置き換えても同様である。
- スコア化を行わない場合、両端のスコア化可能パターンが温存される。
問題に適用する
いま、s を左から順に、手法を選びながらスコア化し、s全体のスコアを最大化することを考える。
まず、 は左端にスコア化可能パターンを持たないので、
- 右端のスコア化可能パターンを用いて連続スコア化し、 点を獲得する(と同時に--)か、
- スコア化を行わずに右端のスコア化可能パターンを温存するか
の2択である。
- で1 を選んだ場合は
- 右端のスコア化可能パターンから連続スコア化し、-1 点を獲得し、--。
- スコア化を行わず、右端のスコア化可能パターンを温存する。
- で2 を選んだ場合は
- 右端のスコア化可能パターンから連続スコア化し、 点を獲得、--。
- スコア化を行わず、右端のスコア化可能パターンを温存する。
- 左端のスコア化可能パターンから連続スコア化し、
- 点を獲得し、右端のスコア化可能パターンを失う。
- ( のとき) -1 点を獲得し、右端のスコア化パターンを温存する。
以上のパターンの内、 のスコア化手法に影響があるのは の左端のパターンであり、これで分類すると
- の左端にスコア化パターンあり (1.2, 2.2, 2.3.2)
- の左端にスコア化パターンがなく
- が減少していない (2.3.1)
- が減少している (1.1, 2.1)
それぞれのカテゴリーで最大になるスコアを保存し、についても同様に計算をしていけば、s全体で得られるスコアの最大値が求められる。