1. 程式人生 > >【NOIP 2018】保衛王國(動態dp)

【NOIP 2018】保衛王國(動態dp)

題目連結

 這個$dark$題,嗯,不想說了。雖然早有聽聞動態$dp$,但到最近才學,如果你瞭解動態$dp$,那就能很輕鬆做出這道題了。故利用這題在這裡科普一下動態$dp$的具體內容。

首先大家肯定都會這道題的$O(n^2)$的做法,這是一個很經典的樹形$dp$。具體來講就是一下兩個轉移:

$$f_{x, 0} = \sum_{v} f_{v, 1} \qquad  f_{x, 1} = a_{x} + \sum_{v} min(f_{v, 0} , f_{v, 1})$$

其中$f_{x, 0/1}$表示$x$這個點選/不選時$x$這個子樹下的最少花費,$v$是$x$的親兒子。

 問題在樹上,我們通常考慮樹鏈剖分,並用$s(x)$表示$x$的重兒子。同時我們引出有關$x$新函式$g$如下:

$$g_{x, 0} = \sum_{v, v \neq s(x)} f_{v, 1} \qquad g_{x, 1} = a_{x} + \sum_{v, v \neq s(x)} min(f_{v, 0}, f_{v, 1})$$

 於是有關$f$的轉移可以改寫成:

$$f_{x, 0} = f_{s(x), 1} + g_{x, 0}   \qquad   f_{x, 1} = min(f_{s(x), 0}, f_{s(x), 1}) + g_{x, 1}$$

 這麼做的目的在於把重兒子單獨分離開來,這樣在$g$中是不包含重兒子的資訊的。我們過一會就能看到它的用處。

上述改寫後的是一個有加法和取$min$的一個轉移,我們把矩陣乘法中的乘法變成加法,把加法變成取$min$,那我們可以用一個線性變換來描述它:

$$\begin{bmatrix}\infty & g_{x,0} \\g_{x,1} & g_{x, 1} \end{bmatrix}\begin{pmatrix} f_{s_{x},0} \\f_{s_x,1}\end{pmatrix}=\begin{pmatrix}f_{x,0} \\f_{x,1}\end{pmatrix}$$

特別的,我們有單位矩陣: $\begin{bmatrix}0 & \infty \\\infty & 0 \end{bmatrix}$。

這麼做的好處在於原本一個自下而上的$dp$,可以被轉變為矩陣乘法,一個點$x$的$f$可以由$x$點到它所在的重鏈的鏈尾上所有矩陣的乘積表示。