å ¸åç㪠DP ã®å®è£ ã®å±æ§ã®ä¸ã¤ã¨ãã¦ãé ã DPã»ããã DP ã¨å¼ã°ãã¦ãããã®ãããã¾ãã ããã DP ãéãã DP ã¨å¼ã¶æ´¾é¥ããã£ãæ°ããã¾ãããããã§ã¯å称ã«ã¤ãã¦ã®è°è«ã¯ãã¾ããã
å°å ¥
åå¿è åãã®è§£èª¬ã®å¤ãã§ã¯ãããããµãã¯åé¡ã® DP ãªã©ãä¾ã«åºãã¦ã
for i in 0..n { for j in 0..=cap { dp[i + 1][j] = dp[i + 1][j].max(dp[i][j]); } for j in 0..=cap - w[i] { dp[i + 1][j + w[i]] = dp[i + 1][j + w[i]].max(dp[i][j] + v[i]); } }
ã§æ´æ°ããã®ãé ã DP ã§ã
for i in 1..=n { for i in 0..=cap { dp[i][j] = dp[i][j].max(dp[i - 1][j]); } for j in w[i - 1]..=cap { dp[i][j] = dp[i][j].max(dp[i - 1][j - w[i - 1]] + v[i - 1]); } }
ã§æ´æ°ããã®ãããã DP ã§ãã¼ã¨èª¬æããããã¨ãå¤ãããªæ°ããã¾ãã
ãããdp[i][j]
ãå³è¾ºã«ããã左辺ã ãã«ããããã¨ãã§èª¬æãããã¡ãªæ°ããã¾ããããã¾ãæ¬è³ªçã§ãªãæ°ããã¾ãã
ã«ã¼ãã®ç¯å²ãå¤ããã ãã§è¦ããä¸ã¯å¤ãã£ã¦ãã¾ãããã§ãã
for i in 1..=n { for j in 0..=cap { dp[i][j] = dp[i][j].max(dp[i - 1][j]); } for j in 0..=cap - w[i - 1] { dp[i][j + w[i - 1]] = dp[i][j + w[i - 1]].max(dp[i - 1][j] + v[i - 1]); } }
ãããããããããµãã¯åé¡ã¯åç´ãªè¨ç®ã§ã§ãã¦ãã¾ããããé ãã»ãããããã¾ãå¼ã³åããã®ãé£ããã¨ãããããããä¾ã«åºãã¦åºå¥ãããã¨ããã¡ãªãããèãæ°ããã¾ãã ã¾ãããã®ä¾ã®ããã§ãé ãã»ãããã¯ããã¾ã§å®è£ æ¹éã®éãã ãã§ãã©ã㪠DP ã§ãåæ¹ãè¡ãæ¥ãããã¨ã容æãã®ãããªæè¦ã«ãªããããæ°ããã¾ãã
主張
$\gdef\DP{\operatorname{dp}}$
以ä¸ã§ã¯ã$\DP[i]$ ã®ããã«æ·»åãä¸ã¤ã® DP ã®ã¿ãèãã¾ãã$\DP[i][j]$ ã®ãããªãã®ã«ã¤ãã¦ã¯ãé©å® $\DP[i\times n+j]$ ã®ããã« encode ãããªã©ãã¦å¸°çãããã°ããã§ããå¿ è¦ã«å¿ãã¦ãencode ããæ´æ°ã $\angled{i, j}$ ã®ããã«è¡¨ããã¨ã«ãã¾ãï¼$\DP[\angled{i, j}]$ ãªã©ï¼ã
$\DP[i]$ ã®è¨ç®ãããããã« $\DP[j]$ ã®å¤ãå¿ è¦ã¨ããã¨ãã$j\to i$ ã«è¾ºãæã¤ã°ã©ããèãã¾ã*1ã DP ã®å®ç¾©ã«ãã£ã¦ã¯ãå¿ ãããï¼æ´æ°ã®æå³ã§ã®å¤§å°é¢ä¿ã¨ãã¦ï¼$j\lt i$ ã¨ã¯éããªããã¨ã«æ³¨æãã¦ããã¾ãã
(* note: å ¨ä½ãæ¸ãã¦ãã Introduction to Algorithms ãèªã¿ç´ããã¨ãããä¸è¨ã®ç¶æ³ã§ $i \to j$ ã®è¾ºãå¼µãã°ã©ãã subproblem graph ã¨ãã¦è¨è¼ããã¦ãã¾ãããæ¸ãç´ãã®ã大å¤ãªã®ã§ãã®ã¾ã¾ã«ãã¦ããã¾ãã*)
ã°ã©ãã«é¢ãã¦
ã°ã©ããç¥ããªã人ã¸ï¼ ãã¨ãã° $y = x^2+1$ ã®ãããªã°ã©ãã®è©±ã§ã¯ãªãã§ããããã¤ãã®ä¸¸ï¼é ç¹ã¨å¼ã°ãã¾ãï¼ãã¡ããããã¤ãã®ç¢å°ï¼è¾ºã¨å¼ã°ãã¾ãï¼ã§çµãã ãçµã°ãªãã£ãããã¦å¾ãããçµµã®ãã¨ã ã¨æã£ã¦ãããã°ããã¨æãã¾ãã詳ããç¥ãããå ´åã¯ãã°ã©ãçè«ãã¨ãã§ã°ã°ãã¨ããããã§ãã
競ããåå¿è ã§ããã°ã©ããã«è¦ææèããã人ã»ã°ã©ãé¢é£ã®ã¢ã«ã´ãªãºã ãããããã«è¦ããã§ãã人ã¸ï¼ ããã§ã¯ãããã話ã¯åºã¦ããªãã®ã§è½ã¡ã¤ãã¦ãã ãããããã¾ã§é ç¹ã®éåã¨è¾ºã®éåãèãããã ãã§ãã
é ç¹ $i$ ã«å ¥ã£ã¦ãã辺ãæã¤é ç¹ã®éåã $\delta_-(i)$ ã¨æ¸ããã¨ã«ãã¾ããã¾ããé ç¹ $j$ ããåºã¦ãã辺ãæã¤é ç¹ã®éåã $\delta_+(j)$ ã¨æ¸ããã¨ã«ãã¾ãã ã¤ã¾ãã$\DP[i]$ ãè¨ç®ããããã«ã¯ãå $j\in\delta_-(i)$ ã«å¯¾ã㦠$\DP[j]$ ãè¨ç®ããã¦ããå¿ è¦ãããã¨ãããã¨ã§ãã éã«ã$\DP[j]$ ãè¨ç®ãçµããããå $i\in\delta_+(j)$ ã«å¯¾ã㦠$\DP[i]$ ã®è¨ç®ã«ä½¿ãæ å ±ã®ä¸ã¤ãããã£ããã¨ã«ãªãã¾ãã
ãã¦ãã°ã©ãèªä½ã¯ï¼å®è£ ã«ãããï¼DP ã®å®ç¾©ã¨å ¥åã±ã¼ã¹ããå®ã¾ãã¾ããããã®ã°ã©ããå¾ããã¨ãç°¡åã¨ã¯éãã¾ããã ããªãã¡ãå®è£ ããä¸ã§ã¯æ¬¡ã®ãã¨ã大äºã«ãªã£ã¦ãã¾ãã
- $i$ ãã $\delta_-(i)$ ãè¨ç®ãããã¨ã¯å®¹æãï¼
- $j$ ãã $\delta_+(j)$ ãè¨ç®ãããã¨ã¯å®¹æãï¼
ã¨ãããã¨ã§ããåè ã容æãªã¨ãã«ãããå©ç¨ãã¦æ±ããã®ããããã DPããå¾è ã容æãªã¨ãã«ãããå©ç¨ãã¦æ±ããã®ããé ã DPãã¨ããç¹å¾´ã¥ããã§ããã¨æã£ã¦ãã¾ãã å¾è ã«åºã¥ãã¨ãã§ããé©åãªé åºã§è¨ç®ãããªã©ãã¦ã$\DP[i]$ ã®è¨ç®æã«ã¯å $j\in\delta_-(i)$ ã®è¨ç®ã¯çµãã¦ãããã¨ãæ ä¿ããå¿ è¦ãããã¾ãï¼å¾è¿°ï¼ã
ããã DP 㯠$\DP[i] = f(\delta_-(i)) = f(j_1, j_2, \dots)$ ã®ããã«ãçå¼ã®å½¢ã§ã®è¨è¿°ã¨ç¸æ§ãããããã§ãï¼$\DP[i]$ ã®è¨ç®ã®éã¯ããã«å¾ãã°ããï¼ã ä¸æ¹ãé ã DP 㯠$\DP[i] \gets g(\DP[i], \DP[j])$ ã®ãããªæ´æ°ãç¹°ãè¿ããããããããé¨åã¯è¦æããã§ãã
ããã DP 㯠âé¢æ°åâ ã£ã½ãã¦é ã DP 㯠âæç¶ãåâ ã£ã½ãã¨ããè¦æ¹ãã§ãããã§ãã æç¶ãåãããé¢æ°å風ã®æ¹ãä¸å¤æ¡ä»¶ãæ£å½æ§ãªã©ãèããã¨ãã楽ãããªã®ã§ãã¢ã«ã´ãªãºã ã®æç§æ¸ãªã©ã§ã¯ããã DP ã£ã½ãå½¢å¼ã®ãã®ãå¤ãæ¸ããã¦ãããããªå°è±¡ãããã¾ããæ°ã®ããããããã¾ããã
ã¾ããããã DP ã§ã¯ãè¤æ°ã®ãã®ãããªã«ããè¨ç®ããå¦çããé ã DP ã§ã¯ãè¤æ°ã®ãã®ã«æ´æ°ãããå¦çããå¿ è¦ã«ãªãã$\delta_{\pm}$ ã®è¨ç®ã ãã§ã¯ãªããããããå®ç¾ãããã¼ã¿æ§é ã¨ã®ç¸æ§ãéè¦ã§ããä¸è¬ã«ãåè ã¿ã¤ãã®ãã¼ã¿æ§é ã®æ¹ãå å®ãã¦ããå°è±¡ãããã¾ãã
ä¾
ããããµãã¯åé¡
ããããµãã¯åé¡ã®ä¾ã§ã¯ã$\DP[i][j]$ ããå é $i$ åã®ååã®ãã¡ãéãã $j$ ã¨ãªãçµåãã®ä¾¡å¤ã®æ大å¤ãã¨ãã㨠$(i, j) \to (i+1, j)$ ããã³ $(i, j) \to (i+1, j+w_i)$ ã®è¾ºãå $(i, j)$ ã«å¼µããããã¨ã«ãªãã¾ãã ããªãã¡ãä¸è¨ã®ããã«è¡¨ãã¾ãï¼å¯¾è±¡ã®ç¯å²å¤ã«ãªã辺ã¯é©å®ç¡è¦ãããã¨ã«ãã¾ãï¼ã $$ \delta_+(\angled{i, j}) = \{\angled{i+1, j}, \angled{i+1, j+w_i}\}. $$ ä¸æ¹ãéåããç°¡åã«æ±ãããã¨ãã§ãã¾ãã $$ \delta_-(\angled{i, j}) = \{\angled{i-1, j}, \angled{i-1, j-w_{i-1}}\}. $$
ãã£ã¦ãã©ã¡ãã«åºã¥ããèãã§å®è£ ãã¦ã大ä¸å¤«ããã§ãã
Eratosthenes ã®ç¯©
ããã DP ã¨è¦åãã¦ããåå¿è ã¯ãã¾ãå¤ããªãã®ããããã¾ããããDP ã¨è¦åãã¾ãã $\DP[i]$ ã®å®ç¾©ã¯ãã$i$ ãç´ æ°ã§ããããæå³ãã boolean ã§ãã
$i$ ãåææ°ã®ã¨ãã«ãµããå¿ è¦ã¯ãªãã®ã§ã$\delta_+(i) = \emptyset$ ã¨è¨ãã¾ãã $i$ ãç´ æ°ã®ã¨ãã¯ã$\delta_+(i) = \{i\cdot j \mid j \gt 1\}$ ã§ãã ãããã¯å®¹æã«è¨ç®ãããã¨ãã§ãã¾ãã$\DP[i'] \gets \DP[i'] \wedge \DP[i]$ ($i'\in\delta_+(i)$) ã§æ´æ°ããããã§ããã
ä¸æ¹ã$\delta_-(i)$ ã容æã«è¨ç®ãããã¨ã¯å¯è½ã§ããããã ãããå¯è½ã§ããã®ãªãããããã篩ãªãã¦ãã®ã使ããã«é«éã«ç´ å æ°å解ã§ãã¦ãã¾ããã§ããã*2ã
ãã£ã¦ãããã¯é ã DP ã¨ã¯ç¸æ§ãããã§ãããããã DP ã¨ã¯ç¸æ§ããããªãããã§ãã ç·å½¢ç¯©ãªã©ãåæ§ã§ãã
åæ°ã®æå¾ å¤ã»ã²ã¼ã ãªã©ãæä½ãä¼´ããã®
ä¸ããããç¶æ ï¼ç¤é¢ã¨å¼ãã§ãããï¼ããçµç¶æ ã«å°éããã¾ã§ã®æä½åæ°ã®æå¾ å¤ããäºäººã²ã¼ã ã®åæå¤å®ï¼ä¸»ã«ãæä½ã§ããªããªã£ã人ãè² ãï¼ãªã©ã®åé¡ã¯é »åºã§ãã ãããã®åé¡è¨å®ã«ããã¦ã¯ãèªæãªã±ã¼ã¹ã¯çµç¶æ ã§ãï¼ãããããæå¾ å¤ã¯ 0ãããã®å±é¢ã¯è² ãç¶æ ããªã©ã¨ãããï¼ã ãã®ãããæä½å¾ã®ç¶æ ããæä½åã®ç¶æ ã«åãã£ã¦è¾ºãåããå½¢ã«ãªãã¾ãã éåæãæã¤äººãããããã§ãããâç´æâ ã«æ¯ãåãããªãããã«ãã¾ãããã
ãã¦ãããããåé¡è¨å®ã«ããã¦ã¯ã$\delta_-(s)$ ã¯ãç¤é¢ $s$ ããæä½ãä¸åº¦ããã¨ãã®ç¤é¢ï¼ãã¡ï¼ãã$\delta_+(s)$ ã¯ãæä½ãä¸åº¦ãããã¨ã§ç¤é¢ $s$ ã«ã§ããç¤é¢ï¼ãã¡ï¼ããæããã¨ã«ãªãã¾ãã åé¡è¨å®ã«ãã£ã¦ã¯ã©ã¡ããèãããã¨ãå¯è½ã§ãããããæä½ãåé¡æã§ä¸ãããããã¨ãèããã¨åè ã®æ¹ãèªç¶ã«ãªããã¨ãå¤ãæ°ããã¾ãã
çµç¶æ ãã $\delta_+$ ãç¹°ãè¿ããã¨ã§åæç¶æ ã«è¾¿ãã¤ãã®ã¯èªæã§ã¯ãªãã£ãããåæç¶æ ããå°éã§ããªãç¡é§ãªç¤é¢ãè¨ç®ãã¦ãã¾ããã¨ãå¤ãã§ãã ã¾ããåæç¶æ ãã $\delta_-$ ãç¹°ãè¿ãã°ãåæç¶æ ããå°éå¯è½ãªç¤é¢ã®ã¿ã«çµããã¨ãã§ãã¦ãããããã§ãã
$\delta_-$ ã§ããã°ã¡ã¢åå帰ã¨ç¸æ§ãããã§ããä¸è¬ã«ãè¨ç®é åºãèªæã§ãªãã¨ãã¯ã¡ã¢åå帰ããããã¨ãå¤ããã§ããDP ã®ã°ã©ãã DFS ãã¦ããã®ã«ç¸å½ãããã§ãã ããã§è¨ã㨠BFS ã§ããããããªæ°ããã¾ããããã¾ãããããå®è£ ããããã¨ã¯å°ãªããããªæ°ããã¾ãã
ããããã®ãããªåç´ãªè¨å®ã§ã¯ DP ã®ã°ã©ãããã¹ã°ã©ãã«ãªããããã´ã¼ã«ãã¹ããé ã«ã«ã¼ãããå®è£ ã®æ¹ãåç´ã«ãªããã¨ãå¤ãã§ãããã ã²ã¼ã ç³»ã«éãããã«ã¼ãã§ç°¡åã«æ¸ãããã©ããã¯ã°ã©ãã®å½¢ç¶ã«ããããã§ããã
æçè·é¢
ãã¿ã¾ãããããæªããã§ããç°¡åãªä¾ã¨ãã¦è² 辺ãããã°ã©ããããã½ä¸å¯è½ãªæåã°ã©ããªã©ãèããã¨ãããããããããã§ããããã®ç¯ã¯ãªãã£ããã¨ã«ãããã§ãã
Dijkstra æ³ã DP ã¨è¦åãããã§ãã DP ã®æ´æ°ã®é åºã¯åçã«æ±ºã¾ãã¾ããåé¡ã¯ãªãã§ãããã
ã°ã©ãã®è¾ºããã®ã¾ã¾ $\delta_+$ã»$\delta_-$ ã«ãªãã®ã§ãã°ã©ãã®è¡¨ç¾ã®ä»æ¹ã«ããããã§ãããæ®éã®é£æ¥ãªã¹ããæã£ã¦ããã° $\delta_+$ ãè¨ç®ããæ¹ãèªç¶ã«ãªãããã§ãã ãã¼ããã $i$ ãåãåºãããã° $j\in\delta_-(i)$ ã«å¯¾ã㦠$\DP[j]$ ãè¨ç®ããããã¨ã«ãªãã¾ãï¼è¨ãã»ã©èªæã§ã¯ãªããããªæ°ããã¾ãï¼ã
ææ
ãããDP 㯠DAGããªã©ã¨è¨ããã¾ããã辺ã®è¨ç®ã®é¨åã«çç®ãã¦ãããã®ã¯ãã¾ãè¦ãªãã£ããããªæ°ããã¾ããã
See also:
- https://tayama-2.hatenadiary.org/entry/20111210/1323502092
- https://kmyk.github.io/blog/blog/2019/09/19/dp-is-not-shortest-path-of-dag/
- https://qiita.com/hibit/items/ecfae3777cf56ac6281b
ãããããªè¦æ¹ãã§ããããã«ãªãã¨çºæ³ã®å¹ ãåºããããã§ãã
ããã
è¿ããã¡ã«ã¾ã DP ã®ã話ãããäºå®ã§ãã次ã¯å ¸åçãªå種 DP ã«é¢ããã話ã§ãã
*1:ã°ã©ãã®é ç¹éå㯠$\N$ ã®é¨åéåã§ããå¿ è¦ã¯ãªãã®ã§ã$\DP[i][j]$ ã®ãããªã¿ã¤ãã® DP ã§ã $(i, j)\to(i', j')$ ã®ãããªã°ã©ããèãã¦ãããã£ãã§ãããããã¾ãããã§ã®æ¬è³ªã§ã¯ãªãããã§ãã
*2:篩ã¯ç´ æ°å¤å®ã ãã§ãªãç´ å æ°å解ãã§ãããã§ãããã