阿斯蒂芬小技巧——枚举子集时间复杂度证明

在写 状压dp 时,经常会见到如下句子:

for(int i=0;i<(1<<n);i++){
	for(int j=i;j!=0;j=(j-1)&i){
			
	}
}

时间复杂度证明如下:

单个 \(x\) 枚举子集复杂度易证( 设 \(y=log_2(x)\) ):

\[∑_{i=0}^{y} C^i_y \]

使用二项式定理

\[(a+1)^n=∑_{i=0}^{n}C_n^i ~ a^i \]

将上面的 \(a\) 设为1,则有:

\[2^n=∑_{i=0}^{n}C_n^i \]

也就是说这一坨的复杂度就是 \(2^y\)

\[∑_{i=0}^{y} C^i_y \]

接着将 \(x\) 分别取 \(0\)~\(2^n-1\),复杂度即为:

PS:这里到 \(2^{n-1}\)是因为 \(2^{n-1}\) 最多有 \(n-1\) 个2

\[∑_{i=0}^{n-1} C^i_{n-1}~2^i \]

然后再使用二项式定理:

\[(a+1)^n=∑_{i=0}^{n}C_n^i ~ a^i \]

把 a=2 带进去会发现:

\[3^n=∑_{i=0}^{n}C_n^i ~ 2^i \]

于是就愉悦的证明出复杂度为:

\[3^{n-1} \]

耶耶耶耶耶耶!!🎉🎉🎉🎉🎉🎉🎉

posted @ 2024-08-10 15:14  LEWISAK  阅读(135)  评论(0)    收藏  举报