枚举子集为什么是 O(3^n) 的
这是更新日志
- \(2021/2/9\) 代数推导
- \(2021/2/10\) 组合意义,构建 TOC
枚举子集
枚举子集为什么是 \(O(3^n)\) 的 .
考虑 一种常见的枚举子集方式:
for (int s = u; s; s = (s - 1) & u) {
// s 是 u 的一个非空子集
}
显然单次枚举 \(S\) 的一个子集是 \(O(2^{|S|})\) 的 .
复杂度证明
组合意义天地灭,代数推导保平安。
代数推导
为什么枚举 \(S\) 的所有子集的子集的时间复杂度是 \(O(3^n)\) 的 .
显然枚举大小为 \(n\) 的集合 \(S\) 的复杂度是
\[O\left(\sum_{T\subseteq S}2^{|T|}\right)
\]
不难发现,\(S\) 中大小为 \(l\) 的子集个数是 \(\dbinom nl\),这是简单的组合数学知识 .
转而枚举 \(l\),于是原式就化为
\[O\left(\sum_{i=1}^n\dbinom ni 2^i\right)
\]
然后里面这个东西可以由众所周知的谔项式定理化简
\[\begin{aligned}\sum_{i=1}^n\dbinom ni 2^i&=\sum_{i=1}^n\dbinom ni 2^i1^{n-i}\\&=(1+2)^n-1\\&=O(3^n)\end{aligned}
\]
于是,枚举 \(S\) 的所有子集的子集的时间复杂度是 \(O(3^n)\) 的 .
证毕 .
组合意义
OI-Wiki 那个奇妙的组合意义解法没看懂 .
大概就是考虑每个元素然后计数有多少个集合包含它,吧 .
《这显然是个双射》
Summary
一个集合 \(S\) 所有子集的子集数之和为 \(3^n\) .
感谢 SoyTony 神仙的指导 orz
感谢 fjy666 神仙的指导 orz
感谢 Alpha1022 神仙的指导 orz
以下是博客签名,正文无关
本文来自博客园,作者:Jijidawang,转载请注明原文链接:https://www.cnblogs.com/CDOI-24374/p/15876755.html
版权声明:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0)进行许可。看完如果觉得有用请点个赞吧 QwQ