状态压缩DP 小结
2016-08-06 16:11
176 查看
好久没更新博客了~
最近学了一下状压DP的内容,感觉对状态压缩有一点了解,不过有时候做题的时候总感觉有些吃力。今天做了2道TSP的题,虽然知道套路,但是对细节处理做的还是很不好,主要原因就是因为我对算法的认识还不够深刻吧,有时候碰到没有遇到过的题型的时候,总想着去查资料,没有深入思考过。其实费老强调过这一点。不要题海战术,要以一挡十。以后要改掉这个坏习惯。
言归正传。下面来总结一下,最近学状压DP的收获。
状态压缩就是将一个状态,用2进制的方法,压缩成一个数。
1.解法需要保存一定的状态数据(表示一种状态的一个数据值),每个状态数据通常情况下是可以通过2进制来表示的。这就要求状态数据的每个单元只有两种状态,比如说棋盘上的格子,放棋子或者不放,或者是硬币的正反两面。这样用0或者1来表示状态数据的每个单元,而整个状态数据就是一个一串0和1组成的二进制数。
2.解法需要将状态数据实现为一个基本数据类型,比如int,long等等,即所谓的状态压缩。状态压缩的目的一方面是缩小了数据存储的空间,另一方面是在状态对比和状态整体处理时能够提高效率。这样就要求状态数据中的单元个数不能太大,比如用int来表示一个状态的时候,状态的单元个数不能超过32(32位的机器)。
位操作实现技巧:
如果要获得第i位的数据,判断((data&(0X << i))==0),若真,为0,假,为1;
如果要设置第i位为1,data=(data|(0X1<< i));
如果要设置第i位为0,data=(data&(~(0X1<< i)));
如果要将第i位取反,data=(data^(0X1<< i);
如果要取出一个数的最后一个1(lowbit):(data&(-data))
举个例子来说。
hdu 1565 方格取数
大致题意就是:给你一个n*n的格子的棋盘,每个格子里面有一个非负数。
从中取出若干个数,所取的数所在的2个格子不能相邻,并且取出的数的和最大。
这个题就是很典型的一个状态压缩题。
对于每一行来说,每个数都有两种选择,选或者不选。那么我们就可以用0代表不选,1代表选。
比如说:10101就代表选第1,3,5个数。并且10101=21。
所以21这一个十进制的数就可以表示第一行的这个状态。
这个题的解题思路就是:
1.先枚举所有状态(从0到1<< n)找出不含相邻1的状态,那么这就是满足每一行不相邻的所有合法状态。
2.特殊处理第1行的状态。上一步找到的合法状态都可以作为是第1行的状态。
3.枚举后面的行。后面的行要满足2个条件。一就是没有相邻的1。二是和上一行的1不冲突。找到合法的状态,利用dp求出最大值就好了。
这个是最简单的套路。后面很多类似的题,都是这个套路。
状压dp的大致思想就是这样。
剩下内容写在题解里面吧~
最近学了一下状压DP的内容,感觉对状态压缩有一点了解,不过有时候做题的时候总感觉有些吃力。今天做了2道TSP的题,虽然知道套路,但是对细节处理做的还是很不好,主要原因就是因为我对算法的认识还不够深刻吧,有时候碰到没有遇到过的题型的时候,总想着去查资料,没有深入思考过。其实费老强调过这一点。不要题海战术,要以一挡十。以后要改掉这个坏习惯。
言归正传。下面来总结一下,最近学状压DP的收获。
状态压缩就是将一个状态,用2进制的方法,压缩成一个数。
1.解法需要保存一定的状态数据(表示一种状态的一个数据值),每个状态数据通常情况下是可以通过2进制来表示的。这就要求状态数据的每个单元只有两种状态,比如说棋盘上的格子,放棋子或者不放,或者是硬币的正反两面。这样用0或者1来表示状态数据的每个单元,而整个状态数据就是一个一串0和1组成的二进制数。
2.解法需要将状态数据实现为一个基本数据类型,比如int,long等等,即所谓的状态压缩。状态压缩的目的一方面是缩小了数据存储的空间,另一方面是在状态对比和状态整体处理时能够提高效率。这样就要求状态数据中的单元个数不能太大,比如用int来表示一个状态的时候,状态的单元个数不能超过32(32位的机器)。
位操作实现技巧:
如果要获得第i位的数据,判断((data&(0X << i))==0),若真,为0,假,为1;
如果要设置第i位为1,data=(data|(0X1<< i));
如果要设置第i位为0,data=(data&(~(0X1<< i)));
如果要将第i位取反,data=(data^(0X1<< i);
如果要取出一个数的最后一个1(lowbit):(data&(-data))
举个例子来说。
hdu 1565 方格取数
大致题意就是:给你一个n*n的格子的棋盘,每个格子里面有一个非负数。
从中取出若干个数,所取的数所在的2个格子不能相邻,并且取出的数的和最大。
这个题就是很典型的一个状态压缩题。
对于每一行来说,每个数都有两种选择,选或者不选。那么我们就可以用0代表不选,1代表选。
比如说:10101就代表选第1,3,5个数。并且10101=21。
所以21这一个十进制的数就可以表示第一行的这个状态。
这个题的解题思路就是:
1.先枚举所有状态(从0到1<< n)找出不含相邻1的状态,那么这就是满足每一行不相邻的所有合法状态。
2.特殊处理第1行的状态。上一步找到的合法状态都可以作为是第1行的状态。
3.枚举后面的行。后面的行要满足2个条件。一就是没有相邻的1。二是和上一行的1不冲突。找到合法的状态,利用dp求出最大值就好了。
这个是最简单的套路。后面很多类似的题,都是这个套路。
状压dp的大致思想就是这样。
剩下内容写在题解里面吧~
相关文章推荐
- 状态压缩dp小结
- 状态压缩dp小结
- 状态压缩DP小结
- DP小结-状态压缩-DP建模
- [状态压缩DP/递推/位运算] Pku/Poj Corn Fields 状态DP入门题详细注释。
- 动态规划(DP),压缩状态,插入字符构成回文字符串
- Hdu-5816 Hearthstone(状态压缩DP)
- HDU 4284(状态压缩dp)
- POJ1038 - Bugs Integrated, Inc.(状态压缩DP)
- HDU 3811 状态压缩DP
- HDU 3681 Prison Break(状态压缩dp + BFS)
- CF417D——Cunning Gena(状态压缩DP)
- HDU 3001(状态压缩dp)
- HDU2167 状态压缩DP
- HDU3001(KB2-J 状态压缩dp)
- BZOJ 2669([cqoi2012]局部极小值-状态压缩+dp)
- 【BZOJ4197】寿司晚宴,状态压缩DP
- poj 1038 Bugs Integrated, Inc. 状态压缩dp
- 状态压缩DP-棋盘模型总结
- 状态压缩DP——poj3254Corn Fields