POJ - 2411 插头dp
2017-11-08 22:21
232 查看
题面
题意
给出m*n的矩形,问用1 *2的小矩形填满共有几种方法。方法
此题首先可以逐行递推,枚举两行可以转移的状态,详见状压dp解法,还可以用插头dp的方法,逐个格子递推,具体见图:蓝色表示当前考虑的格子,红色表示此时记录的状态,本质上就是一个格子一个格子覆盖过去,若已经覆盖则直接转移到下一个状态,反之则覆盖上能盖的并更新状态。
代码
#include<iostream> #include<cstdio> #include<cstring> #define ll long long using namespace std; ll n,m,dp[20][20][2050]; int main() { register ll i,j,k; while(~scanf("%lld%lld",&m,&n)) { if(!m&&!n) return 0; memset(dp,0,sizeof(dp)); dp[1][1][0]=1; for(i=1;i<=m;++i) { for(j=1;j<=n;++j) { for(k=0;k<=(1 << n)-1;++k) { if(!dp[i][j][k]) continue; if(k&(1 << (j-1))) { if(j!=n) dp[i][j+1][k^(1 << (j-1))]+=dp[i][j][k]; else dp[i+1][1][k^(1 << (j-1))]+=dp[i][j][k]; continue; } if(j<n-1) { if(!(k&(1 << j))) dp[i][j+2][k]+=dp[i][j][k]; } else if(j==n-1) { if(!(k&(1 << j))) dp[i+1][1][k]+=dp[i][j][k]; } if(j!=n) { dp[i][j+1][k|(1 << (j-1))]+=dp[i][j][k]; } else { dp[i+1][1][k|(1 << (j-1))]+=dp[i][j][k]; } } } } printf("%lld\n",dp[m+1][1][0]); } }
相关文章推荐
- POJ 2411 Mondriaan's Dream ——状压DP 插头DP
- POJ 2411 插头DP
- POJ 2411 Mondriaan's Dream 轮廓线动态规划,插头dp,滚动数组
- POJ 2411 Mondriaan's Dream [插头DP做法]
- 插头DP——从不会到入门(POJ 2411,HDU 1565,HDU 2167,HDU 1693,Ural 1519)
- poj 2411| 插头dp
- poj 2411(插头DP 简单题)
- POJ-2411-Mondriaan's Dream-轮廓线dp(插头dp)
- POJ 2411 Mondriaan's Dream 插头dp
- POJ 2411 Mondriaan's Dream(插头DP,轮廓线)
- poj2411 Mondriaan's Dream 插头dp做法
- poj2411 Mondriaan's Dream【插头dp】
- POJ 2411 (动态规划-状压DP AND 轮廓线DP)
- poj 2411 Mondriaan's Dream(状态压缩DP)
- POJ-2411 Mondriaan's Dream 状态压缩DP
- pojPOJ 2411--Mondriaan's Dream+状态压缩dp
- POJ-3133 Manhattan Wiring 插头DP
- poj 2411 Mondriaan's Dream (状态压缩dp)
- poj 2411(状态压缩dp)
- 【状态压缩dp 入门】POJ - 2411 Mondriaan's Dream