POJ 2411 Mondriaan's Dream(状态DP)
2016-07-01 12:14
423 查看
题意:求用1*2的牌填满n*m的表格有多少种不同的方法;
用2进制的01表示不放还是放,由于第i行只和i-1行有关,因此可以由i-1行每个状态推出由此状态能够到达的第i行的所有状态。将i-1行任一状态A按位取反后得到第i行的起始状态B。
如 i-1行状态:10011
则 第i行状态:01100
其中第i 行的01100中的1表示竖放在i-1和i的牌。
得到第i行的初始状态B时,用搜索扫一道此初始状态B下横着放牌的所有可能状态,把这些状态累加上i-1行状态A的方法数。
dp[i][j]表示第i行获得状态j的方法数。
dp[i][j] += dp[i-1][k] (k是i-1行中可获得j状态的状态)。
需要明白因为有m列,那么每一行的最多的状况数为(1<< m)-1个。求出每一行的满足的状况时有两种思路:①是经由过程dfs的思路,直接搜刮出所有的可能满足的状况 ②直接暴力列举1-(1<< m)-1所有的状况。当然dfs效率比比例列举要快。
用2进制的01表示不放还是放,由于第i行只和i-1行有关,因此可以由i-1行每个状态推出由此状态能够到达的第i行的所有状态。将i-1行任一状态A按位取反后得到第i行的起始状态B。
如 i-1行状态:10011
则 第i行状态:01100
其中第i 行的01100中的1表示竖放在i-1和i的牌。
得到第i行的初始状态B时,用搜索扫一道此初始状态B下横着放牌的所有可能状态,把这些状态累加上i-1行状态A的方法数。
dp[i][j]表示第i行获得状态j的方法数。
dp[i][j] += dp[i-1][k] (k是i-1行中可获得j状态的状态)。
需要明白因为有m列,那么每一行的最多的状况数为(1<< m)-1个。求出每一行的满足的状况时有两种思路:①是经由过程dfs的思路,直接搜刮出所有的可能满足的状况 ②直接暴力列举1-(1<< m)-1所有的状况。当然dfs效率比比例列举要快。
#include<iostream> const int MaxState = 1 << 12; const int Maxv = 12; long long dp[Maxv][MaxState]; long long count; int h, w; void dfs(int i, int state, int col_index) { if (col_index >= w) { dp[i][state] += count; return; } dfs(i, state, col_index + 1); if (col_index <= w - 2 && !(state & 1 << col_index) && !(state & 1 << (col_index + 1))) { dfs(i, state | 1 << col_index | 1 << (col_index + 1), col_index + 2); } } int main() { while (std::cin >> h >> w, h + w) { count = 1; memset(dp, 0, sizeof(dp)); dfs(1, 0, 0);//穷举第一行的所有满足条件的状态 //根据上一行的状态得出当前行的状态 for (int i = 2; i <= h; ++i) { for (int j = 0; j < (1 << w); ++j) { if (dp[i-1][j]) {//前一行j这个状态存在 count = dp[i - 1][j]; dfs(i, ~j&((1 << w) - 1), 0); } } } std::cout << dp[h][(1 << w) - 1] << std::endl; } return 0; }
相关文章推荐
- JFileChooser的简单使用
- Fragment 总结
- Facebook 开源 AI 所使用的硬件平台 'Big Sur'
- Facebook 开源 AI 所使用的硬件平台 'Big Sur'
- Android 双曲线波浪动画(第一发)
- centos7 下安装jdk8
- autoscrollviewpager + indicator 无限滚动
- android-----事件分发机制测试系列(三)
- java实现双向循环链表
- 如何在linux系统centos下通过Eclipse配置opencv
- Web系统大规模并发——电商秒杀与抢购
- Centos6.5 安装 opencv2.4.9
- 【重读MSDN之ADO.NET】ADO.NET连接
- 经济学家的三观
- Android webview加载显示富文本
- 有关数据库 行 锁 的几个问题(rowlock)
- C++类型转换----reinterpret_cast
- 设计模式C++实现(16)——状态模式
- Linux中想进入一个目录、 在目录下创建文件、在文件内部删除文件 各需要什么权限?
- ubuntu下为vim安装youcompleteme插件