阿斯蒂芬小技巧——列舉子集時間複雜度證明

LEWISAK發表於2024-08-10

在寫 狀壓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} \]

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

相關文章