[POJ 3254] & [POJ 2411] & [POJ 1185]

3题都是状态压缩DP,难度是循序渐进的,便一起写了。

Corn Fields

这题属于最基本的状态压缩DP。直接做的时候想了很久也不清楚如何构造DP,看了discuss后明白到,要使用位向量的形式表示一行的情况,并可以用&的方式判断是否能累加上一行的计数值。由此复杂度是O(m*2^n*2^n),便能过了。这种题目太特殊了,某行的情况必须要在一个32位的int里放得下,并且每一行的向量总数不能太多,否则指数时间复杂度是难以承受的。但好像也没有别的办法可以有效求解这类问题。

Mondriaan’s Dream

和3254类似,但这里需要用^来判断竖直方块的情况(平行方块是00,垂直方块是1),并且记录的状态是亦或运算后的结果,这样才能反应下一层看到的上层情况,最后输出末行状态全0的计数值即可。

炮兵阵地

和3254类似,但增加了难度:需要考虑前两行的情况,同时输出的是盘面最大值而不是计数值。虽然有前面两题的基础,但推状态转移时还是想了一下的:需要用一个dp[i][k][kk]形式的数组,记录第i行向量为k且i-1行向量为kk时的最值。由此便能在根据前两行的向量情况更新可行最值了。

但到这里为止算是出了思路,提交的时候还是分别被卡了内存和时间:内存方面,将dp改成滚动数组便ok了,时间方面,当构造第i行最值时记录其可行的解向量,这样到后面便可以根据记录下来的解情况来更新而无需枚举所有2^m*2^m种情况了。