ツバサの備忘録

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

AOJ 2312 - 魔法少女さやかちゃん

問題
提出コード

解法

添え字は0-indexedとします。 区間の総和は、BITや累積和を用いて高速に取得できるものとします。
P_{l,r} = \frac{\sum_{i = l}^{r}S_{i}}{L}
とします。
仮に円環でなく直線上に音符を配置しているとした場合、明らかに音符をK_{i}の昇順に配置するのが最適です。
しかし今回は、音符を並べて円環を作成しています。この場合、
(K_{i}の最小値)...(その他の音符)... (K_{i}の最大値 )...(その他の音符)...(K_{i}の最小値)
となっているはずです。
つまり、円環を2つに分け、二本の直線とみなすと、それぞれが広義単調増加(減少)になっていればよいことがわかります。
あとは、K_{i}を昇順でソートし、二本の直線のうちどちらに配置するか、ということを考えればいいことになります。ということで、以下のようなDPを考えます。

  • dp[i][j] = 片方の右端がi、もう片方の右端がjになっているときの最小コスト(ただし、i = j = 0もしくは i \gt j )

初期値はdp[0][0] = 0です。 dp[i][j]の遷移は、場合分けで表されます。

  • i \neq j-1の場合
    この場合、i-1と同じ直線にiを配置することになります。よって、
    dp[i][j] = dp[i-1][j] + P_{i-1,i}
    となります。

  • i = j-1の場合
    この場合、i-1を配置した直線とは違う直線にiを配置します。
    つまり、iと隣接する音符は、[0,i-1]のいずれか(i-1i-1 = 0のときのみ可能性が存在します)であるため、
    dp[i][j] = min(dp[i-1][x] + P_{x,i}) (ただし0 \leqq x \leqq i-1)
    となります。

これを計算すると、min(dp[n-1][i] + P_{i,n-1})が答えになります。