sgu 131 Hardwood floor

31 篇文章 0 订阅
31 篇文章 0 订阅

题目描述:

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;
}





评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值