BitMask

本文介绍了一个关于数组加和的问题,通过使用二进制位掩码(bitmask)技术来寻找最小的不可由数组元素组合得到的正整数。通过对2^n种状态的遍历,实现了对所有可能加和的有效覆盖。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

二进制位的一个问题。

前几天在做TC时遇到的,题意大概是这样,给你一个数组,取数组里面的数字进行加和运算。然后求最小的不能利用加和得到的正数。

Attention:每次加和时,每个数字最多能用一次。

Sample:

如果数组A为[1,2,3]

那么所有的可能的加和为:1, 2, 3, 4, 5, 6

所以最小的不能得到的正数是7

(数据规模是数组最多为20个元素)

当时我用的方法是暴力DFS, 最多有 2^20中情况。然后把所有的情况扔到数组中,扫描一遍即可。

看题解的时候,发现题解虽然也是用的暴力,但是是用的bitmask,所以学习了一种新方法。

先把题解的代码贴出:

static const int MAX = 100000 * 20 + 1;
bool poss[MAX];
 
int MinNumber(vector<int> S)
{
    fill(poss, poss + MAX, false);
    int n = S.size();
    // All subsets:
    for (int mask = 0; mask < (1<<n); mask++) {
        int sum = 0;
        for (int i = 0; i < S.size(); i++) {
            if (mask & (1<<i)) {
                sum += S[i];
            }
        }
        poss[sum] = true;
    }
    int x = 1;
    while (poss[x]) {
        x++;
    }
    return x;
}
n为数组中元素的个数。所以一共有2^n中状态。

所以开始 1<<n, 表示这2^n种状态。

然后,mask从0到1<<n,表示对数组中元素的取舍状态。

比如mask为3的时候,那么以为着其二进制数位11.表示取数组中的第0个和第1个元素相加。

mask为5则意味着101,表示取数组中的第0个和第2元素相加,而忽略其他元素。

这样就能够获得所有状态的加和。

后面扫描一遍即可了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值