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