枚舉子集為什么是 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 那個奇妙的組合意義解法沒看懂 .

Alpha 神也說了這個做法:

大概就是考慮每個元素然后計數有多少個集合包含它, .

《這顯然是個雙射》

Summary

一個集合 \(S\) 所有子集的子集數之和為 \(3^n\) .


感謝 SoyTony 神仙的指導 orz

感謝 fjy666 神仙的指導 orz

感謝 Alpha1022 神仙的指導 orz


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM