ツバサの備忘録

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

AGC031 B - Reversi

問題
提出コード

解法

まずはじめに、c_{i}c_{i+1}以降も連続していた場合、その連続している部分の石は必ず同じ色になるので、1つの石に圧縮してしまいます。
この操作を行った、残りの石の列について考えていきます。

次のような操作について考えてみます。
f:id:emtubasa:20190317020108p:plain 左側が1番、そこから1ずつ増えていって、右端が9番とします。
ここで、一番上の初期状態から、[4,6]の石に対して操作を行った後、[2,7]の石に対して操作を行うと、上の図の一番下の列のような結果になります。
さて、この操作を見ると、明らかに[4,6]に対して行った操作が意味をなしていません。ということで、[x,y]に対して操作を行うとき、[i,j] (ただしx \lt i \lt j \lt y )の操作は無視してもよいことになります。
さて、次のようなDPを考えます。
dp[i] = i番目までの石に対する列の種類数
場合分けをしていきます。

  • i区間の右端となるような操作を行わない場合
    このように決めた場合、i-1番までに対して操作を行ったときの種類数がそのままi番目までの種類数になります。ので、このパターンについては
    dp[i-1]
    を参照すればよいです。

  • i区間の右端となるような操作を行う場合
    上の図についてみてきたように、j \lt iとなるj区間の左端として、[j,i]に対して操作を行うとした場合、この区間内の操作はどのようにしても1通りにしかなりません。
    さて、上の図において、青い石は3,5,8番目に3つ存在しています。このとき、[3,8]に対する操作は、[3,5]に対して操作を行った後、[5,8]に対しても操作を行うことと等しくなります。
    [3,5]に対する操作は、dp[5]にすでに含まれている(dpの定義が、その場所までの全ての石の色の並び方を網羅していることになっているため)ので、特別な操作を行う必要はなく、結局、i区間の右端となるような操作を行う場合は、
    dp[j] (ただし、jc_{i} = c_{j}かつj \lt iとなる数字のうち最も大きいもの)
    がそのまま新たな種類数となります。

    ということで、
     dp[i] = dp[i-1] + dp[j] (ただし、jc_{i} = c_{j}かつj \lt iとなる数字のうち最も大きいもの)
    という計算を行っていけば、dp[N]が答えになります。
    jは、前計算をするなり、DPの遷移と同時に計算していくことで求められます。

    感想

    今回はA問題を自力で解けなかったので、こちらだけ解くことができました。問題を読んでからわりとすぐに考察を終えることができたので、なかなか良かったかなと思います。
    思考の過程としては割と解法そのままで、まずは連続した部分が必要ないこと、そして片方の区間がもう片方の区間を完全に含んでいた場合に、小さい方の区間の操作が全く意味をなさないことに気づきます。
    その後、2つの区間でダブりがあるものについても、どちらか片方しか操作ができないことがわかり、あとは、上の青い石のような、3つ以上存在するパターンの処理の仕方について考えました。
    明らかに区間DPが通らないので、この処理をどうするかわかれば、1次元のDPができそうだなと思い、悩んでいると、3つの石のうち、一番遠い2つについての操作は、2つの操作に分けることができるということに気づけたので、あとは遷移を丁寧に求め、この問題が解けました。