E - Increment Decrement 解説 by maroonrk
\(A\) が \(1\) つ与えられた場合に問題を解く方法を考えます.
操作 \(2\) だけを考えたときに,列 \(p_1,p_2,\cdots,p_N\) を得るとします. この時の最小コストを考えます. まず,各 \(i\) (\(1 \leq i \leq N\)) について,\(|A_i-p_i|\) のコストがかかります. 次に,操作 \(2\) だけで列 \(p\) を作るのに必要なコストを考えます. 隣接要素の差分の変化に注目すると,これは,\(M \times \sum_{i=0}^N |p_i - p_{i+1}|/2\) だとわかります. ここで,\(p_0=p_{N+1}=0\) としています. 上の式は,\(M \times \sum_{i=0}^N \max(p_{i+1}-p_i,0)\) と書き直すことができます. \(p_i\) を適切に定めて,上記のコストの和を最小化する問題を解けばよいです.
これを素直にDP で解こうとすると,\(dp[i][j]=(i\) 項目までを決定し,\(p_i=j\) であるときの最小コスト\()\) というものを考えることができます.
ここで,\(i\) を固定した時,\(dp[i]\) がどうなっているかに注目すると,これは凸な折れ線になっています. そして,その傾きが変化する点の集合を管理することを考えると,結局この問題は,以下のような単純な貪欲法に帰着されます.
- \(ans=\sum A_i\) と初期化する.
- 多重集合 \(S\) を用意する.最初,\(S\) は \(0\) を \(C\) 個含む.
- 各 \(i\) (\(1 \leq i \leq N\)) について,以下の操作をする.
- \(S\) に \(A_i\) を \(2\) 個追加する.
- \(S\) の最小の要素を取り出して,\(ans\) からこの値を引く.
- \(S\) の最大の要素を削除する.
(ちなみにこれがオリジナルの問題の想定解法です)
これを数え上げにします. \(B_{i,j}\) の各要素について,それが使われる回数がわかればよいです. これは,\(B_{i,j}\) より小さい要素が \(S\) にいくつ含まれているか,を状態としたDP で求められます. 最終的な計算量は,\(O(N^2K(M+K))\) になります.
投稿日時:
最終更新: