枚举子集的方法

首先放代码:

    for(int s1=s,s2;s1;s1=(s1-1)&s)
        s2=s^s1;

其中$s$表示集合,$s_1$表示子集,$s_2$表示补集。

首先一个集合本身就是自己的子集,所以我们给$s_1$赋初值为$s$。

然后有一个关于按位与的性质:若$a<b$,则$a\ominus b\subseteq b$,其中$\ominus$表示按位与。

于是我们可以将$s_1$减一,再和$s$做按位与,就可以得到$s_1$的次小子集。

再详细一点,$s_1$减一,就是把$lowbit(s_1)$位变为$0$,更小的几位变为$1$,然后和$s$做按位与,就是把多余的$1$抹掉。这样得到的就是次小子集。

猜你喜欢

转载自www.cnblogs.com/Hansue/p/12964117.html