解题思路

此题考查对于按位或运算的理解,以及一个处理状态压缩 dpdp 问题时的常用技巧,子集枚举。 根据按位或运算的性质,不难发现 aorb=aa or b = a 当且仅当 aa 的二进制中 00 的位置,bb 相对应的位置必须也是 00,aa 是 11 的位置,bb 对应的位置可以为 11也可以为 00,首先最直观的一个想法就是暴力枚举比 aa 小的所有值去判断,但是这样我们会进行很多次无效的枚举,然后根据上述性质可以在枚举的过程中进行优化,接下来介绍子集枚举。

降序遍历 mm 的所有子集的代码(不会得到 00 ,对于某些题目 00 可能也是合法的子集,需要特殊判断)

for (int i = m; i; i = (i - 1) & m)

证明为什么是降序遍历到所有子集

假设一个当前子集是 ii ,并且要访问下一个比 ii 小的子集,i−1i-1 代表的是,将 ii 的二进制中最右边的一个 11 变成 00,并且将这个 11右边的所有 00 全部变为 11(比如 1212 的二进制是 11001100,1111 的二进制是 10111011),为了使i−1i-1变成新的子集,需要将 i−1i-1 某些位的二进制是 11,在 mm 中相对应的位置是 00 的去掉(这部操作可以通过 &m 实现),这个操作等价于切割 i−1i-1,以确定算术上可以取到的最大值,即按降序排列的 ii 之后的下一个子集。

遍历大小为 nn 的集合的每个子集的子集

for (int i = 0; i < (1 << n); ++i)
  
  for (int j = m; j; j = (j - 1) & i)

证明时间复杂度O(3n)O(3^{n}),n为二进制中1的个数

考虑在第 ii 位,有三种情况:

(1)在 mm 中为 00,那么在子集 ii 中也为 00。

(2)在 mm 中为 11,在子集 ii 中也为 11。

(3)在 mm 中为 11,但是在子集中为 00。

总共有 nn 位,因此有3n3^{n}种组合。

0 条评论

目前还没有评论...

信息

ID
7
时间
ms
内存
MiB
难度
6
标签
(无)
递交数
97
已通过
30
上传者