状态压缩(初识)

注意:状态压缩的集合是无法满足贪心的排序的

一.了解状态压缩之前需要知道的几点

1.(k&-k)在状态压缩和树状数组中都经常能够看到,那么(k&-k)的值是什么含义呢?

这个值是把k的二进制的高位1全部清空,只留下最低位的1,当然如果只有一位1,则保留等于k本身。该操作就是留下k二进制数中最低位的一个1

2.两种相等的形式:i-(i&-i) = i^(i&-i)

他们都表示减去最低位的1,再返回值

3.状态压缩的方法,就是利用二进制数的零一进行模拟。零代表没取,一代表取了。时间复杂度O(2^n)只能用在n小于20的情况下。首先在存储每个元素的时候就按照(1,10,100,1000)的方法来存储,需要枚举所有的子集时可以利用sum[i] = sum[i-(i&-i)] + a[i & -i] 每个sum[i],都表示i在二进制中1取零不取。可以进行初始化,算出每个i的二进制一的个数。

4.代码:

    //bc[i]表示i的二进制表示中一的个数是多少
    bc[0] = 0;
    for (i=1; i<(1<<20); i++)
        bc[i] = bc[i-(i&-i)] + 1;

 for (i=0; i

        sum[0] = 0;
        for (i=1; i<(1<


5.一定要注意的问题:

原数组,存储所有子集的数组,还有用来存储任意个数二进制个数的数组大小都要开到2^n次方。另,当n <= 20时,时间空间都可以容纳2^20

你可能感兴趣的:(状态压缩(初识))