これを解説ACしました。
問題概要
長さ の配列 が与えられる。
配列内の要素を先頭に持っていく/最後尾に持っていく という操作を繰り返してソートしたい。
最低何回ソートをする必要があるか?
言い換え
ソート後の配列の連続部分列かつ の部分列である配列の長さの最大値を から引いたものを求める。
やること
座圧してDPをします。以降は座圧しているものとして考察を進めます。
と定義します。 にのみ の数をもちます。
また、 とします。
の状態 について、全てを考慮すると の数に一致します。
その時の計算量は になってしまうので間に合いません。
実は条件を満たす部分列の性質を考えると の状態は
- まだ1つめを見ていない
- 途中
- 全部見た後
の3つに抑えられます。
なぜなら条件を満たす部分列では が
- 最初に入る
- 最後に入る
- 途中に入る
の3種類しかなく、それぞれの場合で
- は 個以下使われる
- は 個以下使われる
- 個使われる
しかないためです。したがって、配列の先頭から順々に見ていき、DP配列を更新しながら上の3つをチェックしていくとできます。
DP遷移は提出コードを参考にしてください。
時間計算量は最初の座標圧縮により です。