状压 $dp$ .
- 如果把所有元素 $xor\ 1023$ ,那么就等价于集合内元素 $or$ 和为 $1023$ ,去掉任意一个后 $or$ 和不为 $1023$ .
- 设 $f(i,j,k)$ 表示考虑了前 $i$ 个数,前面已经选择的数 $or$ 和为 $j$ ,期望后面选出的数 $or$ 和包含 $k$ 时的方案数.
- 若第 $i+1$ 个数为 $x$ ,不选它,则有 $f(i+1,j,k)+=f(i,j,k)$ .
- 如果选了它,假设能转移到 $f(i+1,j|x,k’)$ ,那么 $k’$ 需要满足:
- $k’|x=k$ .
- $k’|j|x\not= k’|j$ .这是为了保证去掉 $x$ 后就不合法了.
- 如果只考虑满足第一个条件的,就有 $f(i+1,j|x,k\ xor\ (k\&x) )+=f(i,j,k)$ .因为 $x,k$ 都为 $1$ 的位置上可以随便选.
- 还要减去满足第一个条件,但不满足第二个条件的部分. $f(i+1,j|x,(k\ xor\ (k\&x))|(x\ xor (x\& j)) )-=f(i,j,k)$ .
- 后面括号表示 $x$ 对 $j$ 产生的贡献,即将原来的 $0$ 变为了 $1$ .如果 $k’$ 的这些位上也是 $1$ ,就不满足第二个条件了.
- 初始有 $f(0,0,0)=1$ ,答案为 $f(n,1023,0)$ .这样做是 $O(n\cdot 4^{10})$ 的.
- 注意到若 $f(i,j,k)\not = 0$ ,则一定有 $k$ 是 $j$ 的子集.于是枚举 $k$ 时只用枚举 $j$ 的子集.时间复杂度 $O(n\cdot 3^{10})$ .
滚掉第一维,优化空间.
1 |
|