這是更新日志
- \(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