状态压缩求阶乘

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了,有些别扭 :(