我们知道,用DP解决一个问题的时候很重要的一环就是状态的表示,一般来说,一个数组即可保存状态。但是有这样的一些题 目,它们具有DP问题的特性,但是状态中所包含的信息过多,如果要用数组来保存状态的话需要四维以上的数组。于是,我们就需要通过状态压缩来保存状态,而 使用状态压缩来保存状态的DP就叫做状态压缩DP。

一道例题:

HOJ 2662

有一个n*m的棋盘(n、m≤80,n*m≤80)要在棋盘上放k(k≤20)个棋子,使得任意两个棋子不相邻(每个棋子最多和周围4个棋子相邻)。求合法的方案总数。

直接考虑解决这个问题并不容易,我们先来考虑这个问题的退化形式:

现在我们令n=1。则我们可以很容易的想到状态转移方程:

设dp[i][j][0]表示当前到达第i列,一共使用了j个旗子,且当前格子的状态为不放的状态总数,类似的 dp[i][j][1]就是当前格子的状态为放的状态总数。

那么状态转移方程就是

dp[i][j][0]=dp[i-1][j][1]+dp[i-1][j][0];

dp[i][j][1]=dp[i-1][j-1][0];

当n=1的时候这个问题无疑是非常简单的,但是如果我们想模仿这种做法来解决原问题的话,就会遇到这样的问题:如何来表示当前行的状态?

昨天已经提到了一些状态压缩的知识,如果看懂了的话,应该已经明白怎么做了。

对于每一行,如果把没有棋子的地方记为0,有棋子的地方记为1,那么每一行的状态都可以表示成一个2进制数,进而将其转化成10进制。

那么这个问题的状态转移方程就变成了

设dp[ i ] [ j ][k ]表示当前到达第i列,一共使用了j个棋子,且当前行的状态在压缩之后的十进制数为k 时的状态总数。那么我们也可以类似的写出状态转移方程:

dp[ i ][ j ][ k ]=sum( dp[ i-1][ j-num(k) ][ w ] )   num(k)表示 k状态中棋子的个数,w表示前一行的状态。

虽然写出了状态转移方程,但是还是有很多细节问题需要解决:比如,如何保证当前状态是合法的?

最基本的做法是:首先判断k状态是否合法,也就是判断在这一行中是否有2个旗子相邻,然后枚举上一行的状态w,判断w状态是否合法,然后判断k状态和w状态上下之间是否有相邻的棋子。

当然这样做的时间复杂度是很高的,也就是说有很多地方可以优化,比如:判断每一行状态是否合法,可以在程序一开始判断然后保存结果,判断k状态和w状态上下之间是否有相邻的棋子,可以利用位运算,if(k&w)说明上下之间有相邻的棋子等等。

讲到这里,这道题目的做法已经很明确了,请大家自行完成。

另一道例题:

TSP问题

给你n个城市和城市之间的通路的长度,请你找出一条经过所有城市一次且仅经过一次的路线,使得这条路线的长度最短。

问题分析,如果要设计一个状态的话,显然状态与已经走过的城市和你当前所在的城市有关,现在,按照一定的顺序给每个城市一个编号,如果已经走过的城市记为1,没走过的城市记为0,那么已经走过的城市的状态就可以压缩成一个数。所以,该题目的状态表示为:

Dp[i][j]表示已经走过的城市为i,当前所在的城市为j的最短路程。

相应的状态转移方程为dp[ i ][ j]=min( dp[ i ^ (1<<j) ][ k ] + dis[ k ][ j ]  );     i ^ (1<<j)的意思是将j这个城市从i状态中去掉。 dis[ k][ j ] 是k和j之间的距离。

HOJ2665 虽然题意与之相去甚远,但是本质上是一样的,希望大家能够完成这道题目。

状态压缩DP的特点:

状态中的某一维会比较小,一般不会超过15,多了的话状态数会急剧上升而无法压缩,一般来说需要状态压缩的也就是这一维。

状态压缩DP的常见优化:

预处理是最常见的优化,尤其是在棋盘类问题上,比如说例题1,如果我们想进一步提高效率,我们还可以预处理出状态之间是否可以转移而不用在每一次转移中判断。

灵活运用位运算,例题1中if(k&w)就是一个很好的例子。

推荐题目:

除了上述2道题目以外,我还推荐:

HOJ

•   2188 WordStack

•   2798 Globulous gumdrops

•   2800 Artillery Assignment

这一类DP对于编码能力要求比较高,请大家尽力而为。

转自http://blog.csdn.net/lmyclever/article/details/6671923

学习笔记:状态压缩DP的更多相关文章

  1. HDU 3681 Prison Break(状态压缩dp + BFS)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3681 前些天花时间看到的题目,但写出不来,弱弱的放弃了.没想到现在学弟居然写出这种代码来,大吃一惊附加 ...

  2. Victor and World(spfa+状态压缩dp)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5418 Victor and World Time Limit: 4000/2000 MS (Java/ ...

  3. 状态压缩·一(状态压缩DP)

    描述 小Hi和小Ho在兑换到了喜欢的奖品之后,便继续起了他们的美国之行,思来想去,他们决定乘坐火车前往下一座城市——那座城市即将举行美食节! 但是不幸的是,小Hi和小Ho并没有能够买到很好的火车票—— ...

  4. 状态压缩dp初学__$Corn Fields$

    明天计划上是要刷状压,但是作为现在还不会状压的\(ruoruo\)来说是一件非常苦逼的事情,所以提前学了一下状压\(dp\). 鸣谢\(hmq\ juju\)的友情帮助 状态压缩动态规划 本博文的大体 ...

  5. hoj2662 状态压缩dp

    Pieces Assignment My Tags   (Edit)   Source : zhouguyue   Time limit : 1 sec   Memory limit : 64 M S ...

  6. POJ 3254 Corn Fields(状态压缩DP)

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4739   Accepted: 2506 Descr ...

  7. [知识点]状态压缩DP

    // 此博文为迁移而来,写于2015年7月15日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102w6jf.html 1.前 ...

  8. HDU-4529 郑厂长系列故事——N骑士问题 状态压缩DP

    题意:给定一个合法的八皇后棋盘,现在给定1-10个骑士,问这些骑士不能够相互攻击的拜访方式有多少种. 分析:一开始想着搜索写,发现该题和八皇后不同,八皇后每一行只能够摆放一个棋子,因此搜索收敛的很快, ...

  9. DP大作战—状态压缩dp

    题目描述 阿姆斯特朗回旋加速式阿姆斯特朗炮是一种非常厉害的武器,这种武器可以毁灭自身同行同列两个单位范围内的所有其他单位(其实就是十字型),听起来比红警里面的法国巨炮可是厉害多了.现在,零崎要在地图上 ...

随机推荐

  1. 【LOJ】#2670. 「NOI2012」随机数生成器

    题解 矩阵乘法,注意需要快速乘 矩阵2*2 a c 0 1 代码 #include <iostream> #include <algorithm> #include <c ...

  2. web中的相对路径与绝对路径

    1.什么叫绝对路径 相对于WEB应用的跟路径的路径,即任何路径都必须带上contentPath. 2.javaEE中的/代表什么 代表WEB应用的跟路径(需交由Servlet容器处理) 请求转发时. ...

  3. Android中Xposed框架篇-微信实现本地视频发布到朋友圈功能

    微信非常庞大,还好有一些强大的工具,下面就来总结收获的知识. 一.使用adb shell dumpsys activity top命令快速定位页面 二.使用Jadx进行方法跟踪时候如果发现没有结果,可 ...

  4. (转)python的range()函数用法

    使用python的人都知道range()函数很方便,今天再用到他的时候发现了很多以前看到过但是忘记的细节.这里记录一下range(),复习下list的slide,最后分析一个好玩儿的冒泡程序. 转自: ...

  5. 1013 Battle Over Cities (25)(25 point(s))

    problem It is vitally important to have all the cities connected by highways in a war. If a city is ...

  6. [Arc081F]Flip and Rectangles

    [Arc081F]Flip and Rectangles 试题分析 首先考虑如何操作,发现我们只会选若干行和若干列来进行一次取反. 这个东西相当于什么呢?相当于交点不变,然后这些行和这些列的其它点取反 ...

  7. spring boot2集成ES详解

    一:运行环境 JDK:1.8 ES:5.6.4 二:学习内容 如何构建spring-data-elasticsearch环境? 如何实现常用的增删改查? 如何实现对象嵌套也就是1对多这种关系? 三:J ...

  8. bzoj 3996 最小割

    公式推出来后想了半天没思路,居然A是01矩阵..... 如果一个问题是求最值,并那么尝试先将所有可能收益加起来,然后矛盾部分能否用最小割表达(本题有两个矛盾,第一个是选还是不选,第二个是i,j有一个不 ...

  9. Codeforces Round #357 (Div. 2) B. Economy Game 水题

    B. Economy Game 题目连接: http://www.codeforces.com/contest/681/problem/B Description Kolya is developin ...

  10. Codeforces Round #352 (Div. 2) A. Summer Camp 水题

    A. Summer Camp 题目连接: http://www.codeforces.com/contest/672/problem/A Description Every year, hundred ...