【状压】暴力枚举集合

一般需要枚举所有集合, 且是暴力的方法,则范围会很小,不能超过20。

状态压缩:

状态压缩,其实就是将每个任务 task[i] 看作某个 「 十进制数字 」 的二进制上的第 i 位,1 表示该任务被选择,反之不被选择。

用二进制表示集合

对于集合的子集,可以用(i|j)=j,则i是j的子集

这样,对于所有种集合的组成情况,可以用二进制方法方便遍历:一共有1<<k种。k=元素个数

枚举所有子集

// 枚举所有子集
for(int i =0;i<m;i++){
    // 例如i:11001,意思第一个,二个,5个组成的集合
    int state = i;
    while(state > 0){
        int element = state&1;
        state >>= 1;
    }
}

枚举每个集合的所有子集

// 枚举每个集合的所有子集
// 方法1
for (int i = 1; i < m; i++) {
    // 枚举状态 i 的二进制子集
    for (int j = i; j > 0; j = (j - 1) & i) {
        // To Do..
    }
}

// 方法2
for (int i = 1; i < m; i++) {
    // 从 [1, i] 就可以了,后面的一定不会是 i 的子集
    for (int j = 1; j <= i; j++) {
        // 检查状态 j 是不是状态 i 的二进制子集
        if ((i | j) == i) {
            // To Do...
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值