poj 2411 用1x2填充n*m 状态压缩DP
来源:互联网 发布:软件应届生求职怎么样 编辑:程序博客网 时间:2024/05/20 20:18
/*
dp[i][s]为当i-1行满时,i行的状态是s的方案数
i状态是now_s,i-1状态是pre_s,在第i行横向扫描时,
1.
一个位置若是横着放,则下一个状态是now_s<<2|3
且对应i-1的状态是pre_s<<2|3 (上一行这个两个位置必不为空才能不放)
2.
一个位置若是竖着放,则下一个状态是now_s<<1|1
且对应i-1的状态是pre_s<<1 (上一行这个位置必为空才能放)
3.
一个位置不放,则下一个状态是now_s<<1
且对应i-1的状态是pre_s<<1|1 (上一行这个位置必不为空才能不放)
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 12;
typedef long long llt;
llt dp[2][1<<N];
int n, m, now;
void dfs(int col, int now_s, int pre_s)
{
if(col > m) return;
if(col == m)
{
dp[now][now_s] += dp[!now][pre_s];
return;
}
dfs(col + 1, now_s << 1, pre_s << 1 | 1);
dfs(col + 1, now_s << 1 | 1, pre_s << 1);
dfs(col + 2, now_s << 2 | 3, pre_s << 2 | 3);
}
int main()
{
while(scanf("%d %d", &n, &m))
{
if(n == 0 && m == 0) break;
if(n < m) swap(n, m);
memset(dp, 0, sizeof(dp));
dp[0][(1<<m)-1] = 1;//假设上一行一开始是全满的(第一次是虚拟的上一行)
now = 1;
for(int i = 0; i < n; i++)
{
dfs(0, 0, 0);
memset(dp[!now], 0, sizeof(dp[!now]));
now = !now;
}
printf("%lld\n", dp[!now][(1<<m)-1]);
}
}
dp[i][s]为当i-1行满时,i行的状态是s的方案数
i状态是now_s,i-1状态是pre_s,在第i行横向扫描时,
1.
一个位置若是横着放,则下一个状态是now_s<<2|3
且对应i-1的状态是pre_s<<2|3 (上一行这个两个位置必不为空才能不放)
2.
一个位置若是竖着放,则下一个状态是now_s<<1|1
且对应i-1的状态是pre_s<<1 (上一行这个位置必为空才能放)
3.
一个位置不放,则下一个状态是now_s<<1
且对应i-1的状态是pre_s<<1|1 (上一行这个位置必不为空才能不放)
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 12;
typedef long long llt;
llt dp[2][1<<N];
int n, m, now;
void dfs(int col, int now_s, int pre_s)
{
if(col > m) return;
if(col == m)
{
dp[now][now_s] += dp[!now][pre_s];
return;
}
dfs(col + 1, now_s << 1, pre_s << 1 | 1);
dfs(col + 1, now_s << 1 | 1, pre_s << 1);
dfs(col + 2, now_s << 2 | 3, pre_s << 2 | 3);
}
int main()
{
while(scanf("%d %d", &n, &m))
{
if(n == 0 && m == 0) break;
if(n < m) swap(n, m);
memset(dp, 0, sizeof(dp));
dp[0][(1<<m)-1] = 1;//假设上一行一开始是全满的(第一次是虚拟的上一行)
now = 1;
for(int i = 0; i < n; i++)
{
dfs(0, 0, 0);
memset(dp[!now], 0, sizeof(dp[!now]));
now = !now;
}
printf("%lld\n", dp[!now][(1<<m)-1]);
}
}
阅读全文
0 0
- poj 2411 用1x2填充n*m 状态压缩DP
- POJ 2411 大矩形用1X2小矩形填充 状态dp DFS
- POJ 2411 大矩形用1X2小矩形填充 状态dp DFS
- poj2411之用1*2砖块铺满n*m-状态压缩dp
- poj2411之用1*2砖块铺满n*m-状态压缩dp
- poj-2411-状态压缩DP
- poj 2411 状态压缩dp
- poj 2411 状态压缩DP
- POJ 2411 状态压缩DP
- poj 2411 状态压缩dp
- poj 2411 状态压缩dp
- POJ 2411 状态压缩DP
- POJ 2411 状态压缩DP
- poj 2411 (状态压缩dp)
- poj 2411 状态压缩dp
- POJ 2411 状态压缩DP
- poj 2411 状态压缩DP 铺砖块
- poj 2411 状态压缩dp+轮廓线
- 在 Windows 上搭建本地 Jekyll 编译环境时问题汇总
- UC浏览器主界面滑动折叠效果 使用自定义behavior实现 难度五颗星*****
- 《Javascript高级程序设计(第3版)》阅读笔记(持续更新)
- LINUX学习之GIT
- Activity管理器-2
- poj 2411 用1x2填充n*m 状态压缩DP
- win10 资源管理器打开FTP站点跳到IE
- Python图像处理库
- 1023. Have Fun with Numbers (20)
- [重磅,建议收藏]JAVA集合框架中的常用集合及其特点、适用场景、实现原理简介
- Service笔记
- Spotfire经验总结—饼图中显示前5位的数据,其他数据合并为“其他”
- 一文弄懂神经网络中的反向传播法——BackPropagation
- 使用Date和SimpleDateFormat格式化时间