状态压缩求阶乘
update@2011-07-29
long long f[1<<20] = {};
f[0] = 1;//f[2^0 - 1] = f[0] = 1 (0的阶乘为1)
for(int i = 1;i < (1<<n);i++){// 1 到 2^n - 1
for(int t = i; t > 0; t -= (t & -t)){//f(01101) = f(00101) + f(01001) + f(01100)
//1 t = 13
//2 13 -= 1
//3 12 -= 4
//4 8 -= 8
f[i] += f[i ^ (t & -t)];//将某些位变为0 计算和
//1 f[(01101) ^ (01101 & 10011)] = f[01100]
//2 f[(01101) ^ (01100 & 10100)] = f[01001]
//3 f[(01101) ^ (01000 & 11000)] = f[00101]
}
}
//n! = f[(1<<n)-1]
用状态压缩的方法求阶乘,上面的注释是f[13] = f[12] + f[5] + f[9] 的工作过程, t -= t & -t 就是将最开始的t的每位1取出来,取出来的那位1和原来的t异或就把那位变成0了,有些别扭 :(