POJ2411
2015-06-30 11:33
267 查看
题目大意:一个宽w高为h的棋盘,现在要用1*2的多米诺骨牌不重叠地覆盖整个棋盘,问有多少种方案。
h<11,w<11
分析:1.h*w若为奇数,则无解。
2.按行处理。处理第i行时,保证前i-1行全部覆盖,当前行的状态为state。
以f[i][state]表示处理到第i行,第i行的状态为state,且前i-1行全部填满的方案数。
f[i][state]=∑f[i-1][state2]
需要统计有哪些state2可以转移到state。这个可以用dfs来预处理出来。
View Code
h<11,w<11
分析:1.h*w若为奇数,则无解。
2.按行处理。处理第i行时,保证前i-1行全部覆盖,当前行的状态为state。
以f[i][state]表示处理到第i行,第i行的状态为state,且前i-1行全部填满的方案数。
f[i][state]=∑f[i-1][state2]
需要统计有哪些state2可以转移到state。这个可以用dfs来预处理出来。
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<cstring> using namespace std; #define MAXN 2200 vector<int> arr[MAXN]; long long f[2][MAXN],h,w,n,ss; int tt; void find(int s,int t,int i) { if(s==0||i>=n){arr[ss].push_back(t);return;} if(s&1) { if(s&2) find(s>>2,t,i+2); find(s>>1,t^(1<<i),i+1); } else find(s>>1,t,i+1); } int main() { n=11; int z=(1<<n)-1; for(int i=0;i<=z;i++) { ss=i; find(i,z,0); } while(scanf("%d%d",&h,&w)&&(w||h)) { memset(f,0,sizeof f); if(w%2&&h%2) {printf("0\n"); continue; } int z1=(1<<w)-1; f[0][z1]=1; for(int i=1;i<=h;i++) { for(int j=0;j<=z1;j++) { f[i&1][j]=0; for(int k=0;k<arr[j].size();k++) { f[i&1][j]+=f[!(i&1)][arr[j][k]&z1]; } } } printf("%I64d\n",f[h&1][z1]); } }
View Code
相关文章推荐
- 合约广告系统-Hadoop
- JS获取今天是星期几
- LeetCode_Maximum Depth of Binary Tree
- 打包时lib目录下无jar依赖包
- 解决SwfUpload在IE10上不出现上传按钮
- 面试之 android activity 生命周期
- 【Linux】将Vim改造成IDE
- asp.net 中的gridview 之gridview 分页
- 开通博客园学习笔记博客
- wcf 双工
- [LeetCode] Majority Element
- Matlab定义子函数
- 实例-访问网络图片
- argparse - 命令行选项与参数解析
- DevExpress GridControl复合表头(多行表头)设置BandedGridView
- symbol lookup error"问题
- java 语言的基础
- Ajax+jQuery+bootstrap+Java实现异步点赞功能,并限制点击次数
- 微信连WiFi关注公众号流程更新 解决ios微信扫描二维码不关注就能上网的问题
- inux 下查看服务器负载均衡