列舉子集的方法

tyccyt發表於2024-11-21

可能在狀壓dp中運用的會比較多——

首先直接看程式碼(再來解釋):

for(int j=st,t;j;j=(j-1)&st)t=st^j;

其中,st是列舉的集合,j是子集,tj對於st的補集。但是要注意這個辦法沒有列舉空集,需要自行處理

考慮證明一下:

我們分三步,分別證明正確性、不重、不漏:

正確性

由於這個j=(j-1)&st,所以j不可能出現除st有以外的位。

不重

由於j=(j-1)&st所以j是嚴格遞減的,直接證明~

不漏

由於j-1等價於刪去在二進位制下j的最右一位r,並將r後面的二進位制位變為1,但是不能多出一些位,所以我們考慮再&st即可。

相關文章