枚举子集为什么是 O(3^n) 的

这是更新日志

  • 2021/2/9 代数推导
  • 2021/2/10 组合意义,构建 TOC


枚举子集

枚举子集为什么是 O(3n) 的 .

考虑 一种常见的枚举子集方式

for (int s = u; s; s = (s - 1) & u) {
	// s 是 u 的一个非空子集 
}

显然单次枚举 S 的一个子集是 O(2|S|) 的 .

复杂度证明

组合意义天地灭,代数推导保平安。

代数推导

为什么枚举 S 的所有子集的子集的时间复杂度是 O(3n) 的 .

显然枚举大小为 n 的集合 S 的复杂度是

O(TS2|T|)

不难发现,S 中大小为 l 的子集个数是 (nl),这是简单的组合数学知识 .

转而枚举 l,于是原式就化为

O(i=1n(ni)2i)

然后里面这个东西可以由众所周知的谔项式定理化简

i=1n(ni)2i=i=1n(ni)2i1ni=(1+2)n1=O(3n)

于是,枚举 S 的所有子集的子集的时间复杂度是 O(3n) 的 .

证毕 .

组合意义

OI-Wiki 那个奇妙的组合意义解法没看懂 .

Alpha 神也说了这个做法:

大概就是考虑每个元素然后计数有多少个集合包含它, .

《这显然是个双射》

Summary

一个集合 S 所有子集的子集数之和为 3n .


感谢 SoyTony 神仙的指导 orz

感谢 fjy666 神仙的指导 orz

感谢 Alpha1022 神仙的指导 orz

posted @   yspm  阅读(1625)  评论(4编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
历史上的今天:
2021-02-09 浅谈简单动态规划
😅​
点击右上角即可分享
微信分享提示