位运算枚举子集模板

位运算枚举子集模板

给定n个元素,问这n个元素组成的每一个集合的所有子集;

for(int s=0;s<(1<<n);++s){
    for(int sub=s;sub;sub=(sub-1)&s){
         //do something
     }
 }

原理是这样的;

集合S的任何一个子集,在二进制表示下,必然可以通过若干次-1得到;

那按照这个思路,我们的算法流程如下;

假设S0 = S,S0为要枚举的子集,S为集合;

  1. S0 - 1
  2. 判断S0是否是S的子集

那么我们可以加速这个过程,通过&来加速;

因为我们的判断就是集合S中某些为0的位上,S0却是1;

而按位与自然就可以来操作这个过程;


并且还有一个性质,我们枚举的子集必然是按递减顺序得到的;

因为减一之后得到的必定是数值上最接近同时也小于等于子集S0的值。

进一步使用集合S进行与运算后,只是为了约束得到的子集S0只保留所需要的位,那么是显然是较大的数值能够最大化的匹配这些保留的位吧;

参考

知乎某佬

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值