现在的位置: 首页 > 综合 > 正文

状态压缩DP 题目目录

2016年10月18日 ⁄ 综合 ⁄ 共 1929字 ⁄ 字号 评论关闭

POJ 1170
IOI95的题目了,比较简单。题目大意是说要买一些商品,而商店提供了一些组合购买的打折方案,你不能多买东西,问怎样购买最省。怎样表示状态呢?其实很自然想到把当前你要买哪些东西,并且它们分别要买多少作为状态,那么方程就写成:

F(S)=min[for each i in 合法购买方案](F(S’)+cost(i)]

现在的问题就成了如何在实现的时候来表示S。由于只买5种不同商品,每种的数量最多为5件,于是考虑用6进制表示状态,其中权位及表示商品种类,系数就是商品数量,然后再把这个数压缩成一个10进制数,于是在程序中就好处理了。
这样每次转移时先把该状态还原成六进制,然后转移后再压缩即可。时间为O(m*k*6^n),空间O(6^n)。

没用到状态压缩,题目就是用node表示一种方案,把所有方案都存起来,再对方案进行0-1背包式的放入,选择最优解!事实上那个5维数组可以用状态来表示

POJ 1691
这题看起来复杂,其实就是要你找到一种表示当前棋盘状态的方法。由于只有15个方块,很自然又想到了二进制表示,第k位为0表示第k块矩形已经作色,为1就还没有。还有先预处理一个有向图,s->t表示t在s的上方,于是每次转移的时候枚举颜色,然后看一次最多能涂多少(可以证明每次都贪心尽量涂是最好的策略),递归处理就好了。

POJ 1185
NOI01的题目,相当经典的问题。这题其实和CEOI的bugs integreted inc是一样的,同时和上面第一题的方法也一样,就是用三进制来表示当前位置的状态,0表示这格安放炮兵,1表示上面一格有,2表示上面两格有,这样上下的情况就解决了,转移时再枚举一下邻里的情况就可以。还要注意使用滚动数组优化空间,时间O(n*2^m*3^m),空间O(3^m)。

最后再来说下关于实现的问题。
最常用和直接的方法就是记忆化搜索,非常容易实现,传递压缩后的状态即可。当状态规模小,而转移又比较多并且是二进制压缩时时,还可以使用迭代状态空间的办法(iterative through the state space),就是枚举每种组合,然后转移。

抱歉!评论已关闭.