题目描述:
131. Hardwood floor
time limit per test: 0.5 sec.
memory limit per test: 4096 KB
The banquet hall of Computer Scientists' Palace has a rectangular form of the size M x N (1<=M<=9, 1<=N<=9). It is necessary to lay hardwood floors in the hall. There are wood pieces of two forms:
1) rectangles (2x1)
2) corners (squares 2x2 without one 1x1 square)
You have to determine X - the number of ways to cover the banquet hall.
Remarks. The number of pieces is large enough. It is not allowed to leave empty places, or to cover any part of a surface twice, or to saw pieces.
Input
The first line contains natural number M. The second line contains a natural number N.
Output
First line should contain the number X, or 0 if there are no solutions.
Sample Input
2 3
Sample Output
5
反复研究大牛的代码才过的!
写一点心得吧。
这题从数据量就容易知道是状态压缩,而且转移方程也很容易写出来,就是不知道怎样枚举子状态,后来参考了网上某大牛的代码,才发现 哦 ~~ 原来如此,建议大家去看看大牛的题解,真的很赞。
连接地址:大牛博客。。。Orz
代码(基本就是大牛代码的翻版)
#include<iostream>
#include<cstring>
#include<cstdio>
#include<set>
#include<algorithm>
#include<vector>
#include<cstdlib>
#define inf 0xfffffff
#define CLR(a,b) memset((a),(b),sizeof((a)))
#define FOR(a,b) for(int a=1;a<=(b);(a)++)
#define BUG puts("OK")
using namespace std;
int const nMax = 10;
int const base = 10;
typedef long long LL;
typedef pair<LL,LL> pij;
int n,m;
int k;
LL f[2][1<<nMax];
long long ans;
void dfs(int l,int a,int b,bool a1,int b1){
if(l>m){
if(!a1&&!b1)
f[k][a]+=f[!k][(~b)&((1<<m)-1)];
return;
}
if(!a1&&!b1){
dfs(l+1,a<<1|1,b<<1|1,0,0);
dfs(l+1,a<<1|1,b<<1|1,0,1);
dfs(l+1,a<<1|1,b<<1|1,1,0);
}
if(!a1){
dfs(l+1,a<<1|1,b<<1|b1,1,1);
dfs(l+1,a<<1|1,b<<1|b1,1,0);
}
if(!b1){
dfs(l+1,a<<1|a1,b<<1|1,1,1);
//dfs(l+1,a<<1|a1,b<<1|1,0,1);
}
dfs(l+1,a<<1|a1,b<<1|b1,0,0);
return ;
}
int main(){
cin>>n>>m;
if(m<n)swap(n,m);
k=1;
f[0][(1<<m)-1]=1;
for(int i=0;i<m;i++){
CLR(f[k],0);
//memset(f[k],0,sizeof(f[k]));
dfs(1,0,0,0,0);
k^=1;
}
cout<<f[n&1][(1<<m)-1]<<endl;
return 0;
}