状压dp解释及位运算相关介绍

状压dp其实和普通dp没有什么区别,主要差别在于要熟练掌握为运算的处理,我自己在这一方面比较菜, 所以特此总结一下,也方便自己以后查阅。

状压dp主要是将当前比较复杂的状压缩到二进制上表示,一般用于处理这样的问题:

在一个有n个不同元素的集合中,去表示我当前已经取得的元素状态; 

比如如果 n = 3的话 , 0(000)表的是我手中什么都没有, 1(001)表示的是我当前取得了第一个元素, 2(010)表示的是我取得了第二个元素, 3(011)表示我当前已经有了第一个和第二个……。

总结: 先将各n个不同的初始化状态离散化标记,然后将我当前状态用二进制表示,如果i个状态我已经具有了, 那么这一位就是1,否则就是0,然后再转化成10进制表示。

那么如何进行状态的添加和减少呢?这就要用到位运算来解决了。

1、“<<”运算符: 1<

2、“&” 运算符: 可以表示两个集合的交集,也可用来快速确定当前状态中是否存在第i个状态。

比如 n = 4; 我当前的状态为11(1011)也就是我有了1,2,4这三个初始状态, 另外有一种状态是7(0111)有了1,2,3这三个初始状态, 那么两个集合的交集应该 是(0011)也就是3. 所以 7&11 == 3;

再比如: n = 4; 如果我当前状态为 11(1011), 对于11这个数来说如果不将其转化成二进制数的话,很难直观的确定其中是否存在某种状态,但是我们可以用&运 算符 来确定。 (11 & (1<<(i-1))) 如果这个值为0那么当前不存在第i个状态, 否则就存在。

3、"|" 运算符:表示两个集合的并集。可以用于给当前状态加上第i个状态。 

比如: n = 4, 如果当前状态为 11(1011), 另一状态为7(0111), 7|11 =  15(1111), 如果想给7(1011) 加上的三种状态 可以用 7|(1<<(3-1)) = 15(1111). 更通常的写法 x|(1<<(i-1)) 表示如果当前状态为x那么加上第i个状态的值。(如果x已经具有了当前状态那么, x的值不变)。

4、“^”  运算符, x^y 会的如果 x, y 都具有或者都不具有第i个状态,那么的到的值就不会具有这种状态, 反正则具有这种状态。7^11 = (1100)12;

5、 “>>” 运算符: x>>1 表示x/2 也就是去除x中序号最大的那种状态。

以上是基本的符号,以及表示的意思。

你可能感兴趣的:(动态规划,dp,位运算,压缩)