- name
- 動的計画法
- short description
- 動的計画法とは、アルゴリズムの分類のひとつ。対象となる問題を複数の部分問題に分割して、部分問題の答えを記録しながらそのすべてを解くという形のアルゴリズムの総称である。動的計画法に分類されるようなアルゴリズムの実装方法の典型例として、配列をループで埋めていく実装や、メモ化を伴なう再帰による実装がある。
概要
動的計画法 (dynamic programming; DP) はアルゴリズムの分類のひとつである。対象となる問題を複数の部分問題に分割し、部分問題の答えを記録しながらそのすべてを解くという形のアルゴリズムたちを総称して動的計画法と呼ぶ。
分類
動的計画法に分類されるアルゴリズムたちは、さらに細かく分類することができる。また、そのような分類方法もまたいくつかに分類できる。
状態にもとづく分類
- bit DP
- 状態として bitset として表現された集合を持つ DP のこと。bitmask DP などとも呼ばれる。
- 区間 DP
- 状態として区間を持つ DP のこと。
- 木 DP
- なにか根付き木を考え、状態としてその木の部分木を用いる DP のことを木 DP と呼ぶ。木の畳み込みなどとも呼ばれる。
- 桁 DP
- オートマトン DP
- なにかオートマトンを考え、状態としてそのオートマトンの状態を用いる DP のことをオートマトン DP と呼ぶ。
- 連結性 DP
- グラフの接続関係を状態とする DP のこと。 連結 DP や frontier DP や frontier 法風 DP などとも呼ばれる。
- 箱根駅伝 DP
- マッチング (あるいは順列) の個数を数える DP であって「ペアにするのを保留にしている要素の数」を状態の一部に用いる DP のこと。箱根 DP とも呼ばれる。
値にもとづく分類
- 確率 DP
- 値が確率であるような DP のこと。
- 期待値 DP
- 値が期待値であるような DP のこと。
漸化式や実装方法にもとづく分類
- 配る DP
- 更新する側に注目して書いた漸化式にもとづいて実装される DP のこと。
- 貰う DP
- 更新される側に注目して書いた漸化式にもとづいて実装される DP のこと。
- in-place DP
- DP テーブルを in-place に更新していく DP のこと。セグメント木や convex hull trick を使って高速化できることがある。そこで使われる DP の高速化手法のみを指して in-place DP と呼ばれることもあり、その場合は実家 DP やインライン DP とも呼ばれる。
- 戻す DP
- 漸化式を逆向きに使って更新し、なにかを使わなかった場合の値を求めるような DP のこと。DP の高速化手法のひとつ。
- 挿入 DP
- 列を状態とし、その列に要素を挿入することを遷移とするような DP のこと。逆に抜いていく場合もある。
- 二乗の木 DP
- ある種の木 DP を指す。時間計算量が一見 $O(N^3)$ に見えるが実は $O(N^2)$ になっていることから名前が付いた。
- rerooting
- 木 DP をした結果をもとに、すべての頂点についてその頂点を根だとした場合の値を求める DP のこと。全方位木 DP とも呼ばれる。
- Monge DP
- Monge 性を利用する DP の高速化手法のひとつ。あるいはそれを利用した結果のこと。Knuth optimization とか Knuth-Yao speedup とも呼ばれる。
- Alien DP
関数の再帰的定義による理解
再帰的に定義された関数 $f : X \to Y$ をその定義に従って計算するとき、それぞれの $x \in X$ について $y = f(x)$ を記憶しておきちょうど一度のみ計算するようにすれば指数的な爆発を防げ、$O(\vert X \vert)$ 回の漸化式の計算で値が求まる。動的計画法とはこのような事実を利用したアルゴリズムのことである、という見方ができる6。 このとき $X$ は状態の集合であり $Y$ は値の集合である。
ループとメモ化再帰
動的計画法に分類されるようなアルゴリズムの実装方法の典型例として、配列をループで埋めていく実装や、メモ化を伴なう再帰による実装がある。 ただし、競技プログラミングの界隈においては、特に配列をループで埋めていく実装のみを指して動的計画法と呼ばれることもある7。
配る DP と貰う DP
ほとんどの場合、DP はその漸化式をどのように実装するかによって、貰う DP か配る DP のどちらかに分類できる。
$y = f(x_0, x_1, x_2, \dots)$ という形で書かれた漸化式をそのまま用いるのが貰う DP である。 貰う DP の特徴としては、in-place DP などの形の高速化がしやすいことが挙げられる。
$y = f(x_0, x_1, x_2, \dots)$ という形で書かれた元々の漸化式を逆転させて、$x_0, x_1, x_2, \dots$ のそれぞれを主体として $y \gets g(y, x_0); y \gets g(y, x_1); y \gets g(y, x_2); \dots$ のような更新を行うことで $y$ を計算するのが配る DP である。 配る DP の特徴としては、遷移関係と処理の向きが一致しており考えやすいことや、添字に負数がでてきにくく実装しやすいことが挙げられる。
その他
- 動的計画法は関数の再帰的定義と関係があり、再帰は帰納法と関係がある。帰納法においてはその仮定を強めることでむしろ証明がうまくいくことがあるが、動的計画法においても持つ状態や計算する範囲を増やすことで計算がうまくいくことがある。
- 確率は期待値の特殊な場合と見ることができるため、確率 DP も期待値 DP の特殊な場合だと考えることができる。確率 DP や期待値 DP に特有の技法として、「自己ループを確率分布の期待値で潰す8」や「十分小さい確率の遷移を無視する9」などがある。
- 戻す DP の亜種として、関係する要素の影響量や寄与度を計算して修正をする DP がある。
- 有限種類の (計算対象の) 状態を (DP の) 状態とする DP は Earsarchive.org という問題に由来して「耳 DP」と呼ばれることがある1011。
- 漸化式が規則的かつ線形になっている DP では、漸化式を行列と見て行列累乗で計算することができる。
- すでに使った区間の集合を管理するような DP では、使った区間同士の間隔をできる限り未決定のままにしておくこと12や、区間の長さを降順で使うこと12などがよくある。
関連項目
- Dijkstra 法
- Dijkstra 法は動的計画法に分類される代表的なアルゴリズムのひとつである。
外部リンク
- プログラミングコンテストでの動的計画法 - SlideSharearchive.org
- iwiwi による解説スライド
- DPの話 - aizuziaarchive.org
- DP を DAG 上の最短経路を求めることに関連づけて説明した記事
- 競技プログラミングにおける動的計画法更新最適化まとめ(CHT, MongeDP, AlianDP, インラインDP, きたまさ法, 行列累乗) - はまやんはまやんはまやんarchive.org
- hamayanhamayan による DP の問題集
- 「インラインDP」というテクニックに関して - skyaozoraの日記 - TopCoder部archive.org
- 戻すDP - sigma425のブログarchive.org
- sigma425 による戻す DP の解説記事
- 競技プログラミングにおける戻すDP問題 - はまやんはまやんはまやんarchive.org
- hamayanhamayan による戻す DP の問題集
- International Olympiad in Informatics 2016: day2_3. Aliensarchive.org
- Alien DP の語源となった IOI の問題
- AOJ 2439. 箱根駅伝archive.org
- 箱根駅伝 DP の語源となった AOJ の問題
- 二乗の木 DP - (iwi) { 反省します - TopCoder部archive.org
- iwiwi による二乗の木 DP の解説
- 木と計算量 前編 〜O(N^2)とO(NK)の木DP〜 - あなたは嘘つきですかと聞かれたら「YES」と答えるブログarchive.org
- snuke による二乗の木 DP の解説
- AOJ 2439 箱根駅伝 (JAG 夏合宿 2012 day3a-F) (600 点) - けんちょんの競プロ精進記録archive.org
- drken による箱根駅伝 DP の解説
注釈
-
uwi によるツイート https://twitter.com/uwitenpen/status/1229100036450996224archive.org ↩
-
https://twitter.com/shojin_comp/status/1229099045475344384archive.org ↩
-
kort0n によるツイート https://twitter.com/kyort0n/status/1229096380431396864archive.org ↩
-
snuke によるツイート https://twitter.com/snuke_/status/928314561890959360archive.org ↩
-
yosupo によるツイート https://twitter.com/yosupot/status/928313911891214336archive.org ↩
-
chokudai によるツイート https://twitter.com/chokudai/status/1010049288460570624archive.org ↩
-
furuya1223 によるツイート https://twitter.com/furuya1223/status/1189903074107654145archive.org ↩
-
kuuso によるツイート https://twitter.com/kuuso1/status/1189904707067600901archive.org ↩
-
tempura0224 によるツイート https://twitter.com/tempura_cpp/status/1177147483010387968archive.org ↩
-
kanra824 によるツイート https://twitter.com/Md19970824/status/1254015456362459137archive.org ↩
-
例題: https://atcoder.jp/contests/dwacon6th-prelims/tasks/dwacon6th_prelims_e ↩ ↩2
-
sky58 によるツイート https://twitter.com/skyaozora/status/1177173768738705408archive.org ↩