可能在狀壓dp中運用的會比較多——
首先直接看程式碼(再來解釋):
for(int j=st,t;j;j=(j-1)&st)t=st^j;
其中,st
是列舉的集合,j
是子集,t
是j
對於st
的補集。但是要注意這個辦法沒有列舉空集,需要自行處理。
考慮證明一下:
我們分三步,分別證明正確性、不重、不漏:
正確性
由於這個j=(j-1)&st
,所以j
不可能出現除st
有以外的位。
不重
由於j=(j-1)&st
所以j
是嚴格遞減的,直接證明~
不漏
由於j-1
等價於刪去在二進位制下j
的最右一位r
,並將r
後面的二進位制位變為1
,但是不能多出一些位,所以我們考慮再&st
即可。