HDU 5771 Turn Game

给定一个 nm 的全0矩阵,每一次可以将一个 wh 的矩形中的数^1,其中w、h至少有一个为1,求k次之内可以达成的局面数。
T≤600,1≤N≤4,1≤M≤10,K≤N*M

非常喜欢这道题,尤其是在看懂题解之后,觉得非常的有趣。

Fi,mask=min(Fi1,cmask+costrow+costcol) 。考虑S是否可以在K步内得到,只要检查最终列里是否有一个 Fmask 是否小于等于K。整个过程做了一遍逐层的最短路

考虑这个转移中需要记录的信息是每列中的 Fmask ,每列有 2n 个花费。观察可以发现这些花费的最大值最小值之差不会超过n。把每层的花费同时扣除最小的那个状态的花费并将合并这些状态成为一个新的状态。这个状态的总数在n等于4时到达2000多个

把这些状态直接连上边,边包含逐列加入的列的最终染色情况以及两个状态最小转移花费。在这些状态上做一遍DP,就可以得到最快能在K步内得到的方案数,累加一下就是答案。

蒟蒻第一次接触这种把状态点化的题。
充分利用边权的潜力从而减少点的个数的做法非常有趣。
最后回过头来看这题其实挺朴素的,但是也很有魅力。
感谢FZU出了这道题 :)


补充:
一种染色情况转移到另一种染色情况,需要知道前一种染色情况的所有行型矩形的分布和后一种染色情况所有行型矩形的分布。

行型矩形的分布有 2n 种可能,记录每一种可能的代价,再hash成一个点。
代价是前一种染色情况中的 2n 种分布原有的代价,加上到后一种染色情况中的每一种分布的改变代价,加上在用列型矩形调整成目标染色的改变代价的最小值。
比如,之前的分布为1010,其代价是2(随便扯的),当前的分布为0101,1表示有行型矩形,目标染色是1101,原有的行型矩形终结或延续不需要代价,开始2行新的行型矩形代价为2,然后调整到目标染色需要一个列型矩形,代价为1,总的代价就是2+2+1=5。
但是不一定是从1010转移过来的,所以要找最小值。
朴素找最小值的话转移复杂度就是 22n

这样的话点依然是很多的,所以出题人就把这些代价减去最小的代价,这个最小的代价体现在边权上,这样点数少了很多,但还是不容易确定实际会有多少个点,勇敢bfs一遍之后最后发现只有2005个点,(和上限差很多,大概是因为染色比较有规律吧==)就是最后题解复杂度里的 Status ,然后就可以dp了。

开始只有一个点。一个点要到某种染色情况只能走到确定的点,保证不会重复算,一层层的转移就可以保证到每个点的步数(其实就是列数)确定。
另外,这个点是脱离染色情况存在的(代价和前一列的具体染色无关),可能基于之前的代价相同就走到了一起。

dp[i][j] :i列 代价≤j 可以达成的局面数
dp2[i][j][k] :i步后走到j点,最小代价为k的方案数(每个方案对应一种局面)
(dp[i][j]=Statust=1jk=0dp2[i][t][k])

最短路+dp

:P :P :P :P :P :P :P :P :P
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值