[算法模板]SOS DP


[算法模板]SOS DP

正文

SOS-DP(\(\text{Sum over Subsets}\))是用來解決這樣的問題的:

其實就是子集和DP。上面每個\(F[mask]\)里面包含了\(mask\)所有二進制子集的信息。這是一種\(n\log_2 n\)的DP方法。

我們定義一個DP狀態\(S(mask,i)\)代表\(mask\)子集中只有最靠右的\(i\)位與其不同的狀態。

具體是這樣的:

圖中描述了\(S(10110,4)\)這個狀態和其所有兒子之間的關系。

形象一些解釋就是每次我們求解一個狀態時,我們只從他的所有子集里和他只差一位的狀態轉移過來。(眾所周知,如果\(A\subseteq B,B\subseteq C\)那么\(A\subseteq\) C)。

放一段代碼:

for(int i = 0; i<(1<<N); ++i)
	F[i] = A[i];
for(int i = 0;i < N; ++i) for(int mask = 0; mask < (1<<N); ++mask){
	if(mask & (1<<i))
		F[mask] += F[mask^(1<<i)];
}

所以顯然,復雜度\(N\space 2^N\)。如果令值域為\(M\),那么復雜度就是\(M\log_2M\)

例題

CF1208F Bits And Pieces

CF165E Compatible Numbers

CF383E Vowels

參考資料

SOS Dynamic Programming [Tutorial]

SOS DP


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM