本來這一塊是做在「ideas and tricks」裡面的,但是鑑於最近剛學dp優化minmax容斥,而且隨便開了一道又開出乙個神仙整體dp題,所以把它單獨拿出來總結一下。
首先要轉化題意,一般對於「全部滿足」一些限制的時候,可以轉化成所有亂選,然後限定一些一定不成立(前提是不成立的比較好算),進行容斥
然後一般這種題我們會發現容斥出來的答案(或者知道這個就能算出答案)的東西是很好設計成狀態且易於轉移的,所以就可以轉而用dp來表示這種狀態的方案數帶上容斥係數。
例如noi2020d1t2,在考慮樹上進行容斥以後,對於一些點不成立,限制無非就是兒子到父親的一段區間必須染白,所以就可以用$dp[i][j]$表示到第$i$個點,限制最上面到$j$的方案數。
然後樹上的轉移一般又會帶有一些優化,比如說一些求和的問題,在兒子合併時可以通過線段樹合併來優化時空複雜度。
再區別一下這道題(不是整體dp),這個選最大獨立集對兒子合併也是有條件的(不能線段樹合併),但是是區間max,不需要怎麼更新父親資訊,直接長鏈剖分,再輕兒子深度處更新答案即可
對於這道題,直接把樹邊搞成限制,然後如果一些限制強制不成立那麼一定會把這棵樹連成若干條鏈,任意乙個結點入度出度都不能大於等於2。然後直接把有幾條鏈設進狀態裡,dp就很容易了。
有:$$\max(s)=\sum_(-1)^\min(t)$$
$$kthmax(s)=\sum_(-1)^\binom\min(t)$$
這種dp一般有乙個特點:就是列舉子集以後的$min(t)$特別好算而且答案很小
考慮每次列舉子集的時候直接把這個原本的答案設進狀態然後表示集合個數乘上正負係數和組合係數
經典例題如重返現世,我們會發現對於乙個子集的$min(t)$,我們只要知道這個子集裡的$\sum p[i]$即可,而又有$m \leq 10000$,所以就可以把概率總和設進狀態,然後表示集合個數乘上容斥係數。
考慮帶有組合數的遞推式,我們無法直接通過簡單的加減來實現這個轉移,而直接把集合大小記下來狀態又存不下——觀察資料範圍發現$k$非常的小。
組合數是怎麼推的?——$c(n,m)=c(n-1,m-1)+c(n-1,m)$這個$k$表示的就是列數,元素個數一直都是$n-1$,即選上這個元素以後所產生的貢獻可以由$k$和$k-1$之和來表示(帶$k$僅僅是為了組合數轉移)。
所以就有:(選的時候)
$$dp[i][k][s]=dp[i-1][k-1][s-p[i]]-dp[i-1][k][s-p[i]]$$
其中正號負號取決於容斥元素個數奇偶性。
這裡有乙個很好的初始化技巧——可以把$dp[0][0][0]$設成$0$,剩下的$dp[0][k][0]$設成$-1$,這樣在剛好從$t-1$個元素轉成$t$個元素時,這個集合對於選擇$t$個開始有1的貢獻
還有一道與之類似的題:給你乙個長度為$n$的序列,初始全為白色,每次你等概率一段區間$[l,r]$把它染黑,問至少有$k$個元素被染黑的期望步數,$n \leq 100$
考慮一樣的minmax容斥,現在要求$min(t)$,這個也挺好處理,對於所有$n*(n+1)/2$個區間,把所有未選的點所構成的一段段區間,期望就是
$$\frac}-\sum \frac}$$
所以我們$dp[k][j][i]$表示在$k$的情況下$\sum l*(l+1)/2 $的和為$j$,最後乙個選的是$i$。與上面類似遞推即可。複雜度為$n^$,因為只會有$10000$個答案,打表就能過。
(聽說有$n^$較大剪枝的另一種推法?留坑補補)
順便再講乙個minmax常用優化——fwt
例題:pkuwc2018隨機遊走,haoi2015按位或
前者是fwt最後統計方案時是子集卷積,這很容易想到fwt的or操作,對於一些子集的值乘上正負係數直接卷起來就可以處理多次詢問了。
後者則是通過轉化題意,把「至少選到乙個」的概率轉化成「乙個都不選」的概率,然後這一位的補集的卷積就是總概率,fwt可以快速處理。
其實我覺得這個25~40的部分分也挺神的,先講一講。
考慮狀壓dp可以設$dp[s][i]$表示哪些已經選了,最後一位是$i$。但是我們發現沒有必要儲存前面填了哪些數這個資訊,只要知道相對大小即可把很多狀態綁起來轉移,而對於要填的下乙個數只要記錄前乙個數的狀態即可。
所以設$dp[i][j]$表示填到第$i$個數,最後乙個數在已填的數裡面時第$j$大的,然後$n^$轉移,可以優化到$n^$,但是再沒有什麼優化空間。
正解是類似於整體dp的思路,我們先假設把所有小於號提取出來,剩下的大於號隨意,那麼方案數就是$n!\prod \frac$,$l$是每乙個小於號段的長度。
所以可以進行容斥——使得一些隨便選的大於號強制選小於號使連成一段。設$dp[i]$表示到第$i$位的答案,那麼就有方程式:
$$dp[i]=\sum_(n))$
感覺以小結的形式把一些類似的題目總和在一起的方式還是不錯的,雖然有點廢時間。再有時間可能會更新一些有關概率期望的內容。
樹形dp小結
這些天做了一些樹形dp的題目,感覺有了些領悟,尤其是理解到樹形揹包就是分組揹包之後。選出幾道不錯的總結一下 hdu 1520 hdu 4003 poj 1155 poj 2486 hdu 4313 hdu 4340 hdu 1520 入門水題 每個節點有權值,子節點和父節點不能同時選,問最後能選的最...
區間dp小結
區間dp,顧名思義,就是在區間上dp,即把整個區間劃分為乙個個的小區間,在小區間內dp求出最優值,然後把這些小區間合併以後就是整個取件的最優值。下面是一些比較經典的區間dp題目 1.nyoj 737 石子合併 題意 有n堆石子,每堆有a i 個,每次合併時只能合併相鄰的兩堆,代價為兩堆石子的個數之和...
dp基礎小結
kuangbin帶你飛系列,基礎dp 總共20多道題,就不一一說了 說一下學會的關鍵的思路 第1點 有的時候某一狀態的值的得出,可能會要我們列舉已經計算過的值,一一比較取最值,但如果真的去列舉的話就會超時,這時我們可以把狀態的含義設為前i項的最值,計算的時候只需要多比較一項,即和前一項比較一下就可以...