状压dp现在看起来也是比较重要的一块,在联赛里也经常出现,它的位运算繁琐复杂,所以也是相对来说比较难的一种dp,这篇文章里我来讲一下位运算就可以让大家更好地理解状压dp,从而理解、掌握它。
首先要不先讲一下状压dp好了。它通常使用在n十分小的情况下(比如n<=20),虽然是指数级别的复杂度,但速度比搜索快,其思想非常之优秀。所以看到n非常小时,就要想到99%是状压dp。
状压dp的适用情况就是当状态可以由0或者1来表示时,我们所需状态数组无法满足。将状态表示成二进制数转化成十进制通过位运算的处理来进行状态的转移。
所以位运算在状压dp中有着重要的作用。
1.判断一个数字x二进制下第i位是不是等于1。
if(((1<<(i-1))&x)>0)
2.将一个数字x二进制下第i位更改成1。
x=x|(1<<(i-1))
3.把一个数字二进制下最靠右的第一个1去掉。
x=x&(x-1)
4.判断某状态是否有相邻的两者相同。
if(x&x<<1)
5.判断第i为是否为1(这个位是从右数起,从0开始。)
if(x&(1<<i)
if((x>>i)&1)
6.设置第i位为1。
x|=1<<i;
7.设置第i位为0 。
x&=~(1<<i)
8.切换第i位。
x^=1<<i;
……
大概就这几种常见的我列了出来,实际上还有很多,也无法一一列举。