PrepStack · Markdown HTML

位掩码枚举集合

位运算与位掩码状态 · HTML

数学 / 逻辑形态

mask∈[0,2^n);第 i 位表示元素 i;sub=(sub-1)&mask 依次枚举非空子掩码。

识别信号

容易误判的相似信号

SignalWhy it is different
n 较大2^n 很快不可行,应找结构性剪枝或 DP 维度替代。
元素有高重数一个 bit 只能表达是否存在,不能直接表达计数。

核心不变量

mask 与选择集合一一对应;位运算精确模拟集合并、交、删与包含。

状态、转移与处理顺序

ItemDefinition
State当前 mask、元素列表、可选 submask 与目标全掩码 full。
Transition外层 mask 加一枚举所有集合;子掩码用 (sub-1)&mask 删除或重排最低有效位。
Frontier / order数值顺序是编码前沿而非集合大小顺序;每个 n 位编码恰访问一次。

Python 骨架

def all_subsets(items):
    n = len(items)
    for mask in range(1 << n):
        yield [items[i] for i in range(n) if mask >> i & 1]

def nonempty_submasks(mask):
    sub = mask
    while sub:
        yield sub
        sub = (sub - 1) & mask

def is_subset(a, b):
    return a & b == a

正确性思路

  1. n 位二进制串与 n 元集合子集构成双射。
  2. range(2^n) 枚举每个编码一次,故不重不漏。
  3. sub-1 改变当前最低有效 1 及其低位,再与 mask 保证不引入集合外位。
  4. 该递推严格减小 sub,最终到 0。

复杂度

TimeSpaceParameters
全部子集 O(2^n n) 若物化;所有 mask 的所有 submask 总计 O(3^n)O(n) 生成一个子集n 为可选元素数

边界条件

错误模式

PatternWhy it fails / fix
忘记空集range 从 1 开始会漏掉常见基例。
子掩码循环在 0 后继续会回到 mask 形成死循环。
把数值顺序当大小顺序相邻 mask 的 bit_count 不保证单调。

选择与排除规则

相关模板

RelationTemplateBoundary
状态骨架状态压缩 DP用 mask 遍历选择集合
计数替代组合计数 / 容斥只需数量无需枚举
搜索替代子集 / 组合回溯需要剪枝或按路径生成

原创微型例子

环节内容
Resultmask 5(二进制 101)代表选择 A 与 C。
Scenario三种开关 A、B、C。
Walkthrough第 0、2 位为 1;枚举 0..7 得到全部八种组合。

Recall prompts

我的补充