hitoare日記

たまに書きます

Alien DP についてのメモ

Alien DPの自分なりの理解をメモ。

アルゴリズムの説明

 M = ( M_0, M_1, ..., M_n ) を広義で上に凸であることがわかっている未知の数列とする。

与えられた kに対して M_kを求めることを目指す。

 a_i = M_{i+1}-M_i とおくと、 Mが広義で上に凸であることから a_iは広義単調減少である。

この時関数 f_i, g  f_i(x) = -ix+M_i  g(x) = \max\limits_{0 \leq j \leq n}  f_j(x)で定義すると以下の補題が成り立つ。

補題

 x \in [a_i : a_{i-1} ]の時、 g(x) = f_i(x)である。

(ただし便宜上 a_{-1} = \infty, a_n = -\inftyとする)

証明

 a_i \leq x \leq a_{i-1} として、 0 \leq j \leq nに対し f_j(x) \leq f_i(x)を示す。

 j \geq iの時と  j \leq i の時で場合分けする。

 j \geq iの時、

$$ \begin{aligned} f_i(x)-f_j(x) &= -ix+M_i+jx-M_j \\ &= (j-i)x-(M_j-M_i) \\ &= (j-i)x-(a_i+a_{i+1}+\ldots+a_{j-1}) \\ &\geq (j-i)x-(j-i)a_i \\ &= (j-i)(x-a_i) \\ &\geq 0 \end{aligned} $$

である。  j \leq i の場合も同様。

(証明終)

上の補題から、全ての 0 \leq i \leq nに対して g(x) = f_i(x)を満たす xが存在することがわかる。

また、 そのような xが取りうる範囲 [a_i : a_{i-1} ] iが増加するごとに負の方向に移動する。

したがって 0 \leq k \leq nが与えられた時、 g(x) = f_k(x) = -kx+M_k となるような xを求めれば、  M_k = g(x)+kx M_kを求めることができる。

下の画像は M= ( 0, 10, 14, 14, 9 ) の時の f_i(x), g(x)のイメージ。

補足
  •  xが与えられた時に g(x)がそれなりの速度( O(N)とか)で求められる必要がある。

  • 競プロでは M_kを「それぞれにスコアが与えられている何かの集合の中から(条件を満たしつつ) k個選んだ時のスコアの合計の最大値」のように定義した場合、すなわち
     M_k = \max\limits_{S \in {\cal S}, |S|=k} \sum\limits_{t \in S} c_t
    のような形の時、

  
\begin{aligned}  
g(x) &= \max\limits_{0 \leq k \leq n} \left( -kx + \max\limits_{S \in {\cal S}, |S|=k} \sum\limits_{t \in S} c_t \right) \\  
&= \max\limits_{0 \leq k \leq n} \max\limits_{S \in {\cal S}, |S|=k} \sum\limits_{t \in S} (c_t-x) \\  
&= \max\limits_{S \in {\cal S}} \sum\limits_{t \in S} (c_t-x)  
\end{aligned}

と変形でき、DPで g(x)の値と、 f_i(x)=g(x)となる iの値が簡単に求まることがある。

  • 上の議論より、 {M_i}が全て整数ならば g(x) = f_k(x) = -kx+M_k となるような整数 xが存在することがわかる。

  • また、そのような xを二分探索する範囲は [a_{n-1} : a_0 ]を含むように取れば良い。*1

  •  x_0 = a_l = a_{l+1} = \ldots = a_{r-1} の場合、すなわち Mの傾きが [l:r]で単調な場合、全ての i \in [l:r]に対して f_i(x)=g(x)となる。
    後述の問題例のように「 M_k \leq Xを満たす最小の kを求める」ような場合に注意が必要となる。

  • 下に凸な場合は f_i(x) = ix+M_i  g(x) = \min\limits_{0 \leq j \leq n}  f_j(x) とおく。

問題例

atcoder.jp

公式解説より、「 N個のランプのうち隣り合う2つを選ばないように R個選ぶときのスコアの合計の最大値」を求める問題に帰着される。

提出→https://atcoder.jp/contests/abc218/submissions/42826600



atcoder.jp

素直に M_i=(絵をi個選んだ時の価値の総和の最大値)として適用できる。

提出→https://atcoder.jp/contests/nadafes2022_day2/submissions/42869527



atcoder.jp

上の2つと異なり最小値を求める問題。

 M_k \leq Xを満たす最小の k (  =D とおく )を求める必要がある。ここで M_iは下に凸で単調減少である。

公式解説で「上の解説で説明した Alien DP の方法と同様に個数を持って DP して二分探索でも計算できますが、傾きが一定な部分の扱いで少し複雑になるので…」として省略されている二分探索を利用した解法で解いたので、それを紹介する。

 xを固定した時、 g(x) = f_i(x)となる i g(x)が求められれば、何らかの iに対する M_iは求まることと、 M_iの単調性を利用して二分探索すれば良いのだが、

 g(x) = f_i(x)となる iが複数存在する場合は注意が必要である。

最小値を求めるので、補足に書いたように f_i(x) = ix+M_iと置いていたとする。

もし f_l(x) = f_{l+1}(x) =  \ldots  = f_r(x)=g(x), (l < r)かつ M_r \leq X \leq M_lだった場合、単純にDPをするだけでは Dを求められない。

この場合は M_i = g(x)-ix \leq X i \in [l:r] から  i の取りうる範囲を求め、最小値をとれば良い。

提出→https://atcoder.jp/contests/abc305/submissions/42870515

参考にさせていただいた記事

H - Red and Blue Lamps 解説 by Nyaan

Monge グラフ上の $d$-辺最短路長を計算するアルゴリズム | Kyopro Encyclopedia of Algorithms

Ex - Shojin 解説 by Nyaan

*1:実際は [a_k : a_{k-1}]を含んでいれば十分だが、両端のほうが目安をつけやすい