CDOJ 885 方老师买表

Time Limit:1000MS Memory Limit:65535KB 64bit IO Format:%lld & %llu

Status

Description

由于方老师出色的专题讲座,他的名气迅速扩散到全国各地,并通过各地的讲座赚到了很多钱,鉴于现在盛行买表,于是方老师带上了一个 H×W 的盒子去买表,我们假设每一个表占 1×2 或者 2×1 的空间,问方老师有多少种放置表的方式,把这个盒子填满。

Input

输入有多组数据

每组数据占一行,每一行有 2 个正整数 H,W(1H,W11)

Output

对于每组测试数据输出 1 个整数,表示该测试数据的答案

Sample Input

2 10
3 3

Sample Output

89
0

Hint

Source

2014 UESTC Training for Dynamic Programming

解析
状态压缩DP入门题。类似于HDU1992 Tiling a Grid With Dominoes可以看我的另一篇博客 http://blog.csdn.net/liao_jingyi/article/details/40632695
我用的是压缩每一列的状态
注意结束状态必须是1 1 1 1 1 1……1 == (1<<W)-1 (因为不能再向后扩展了)
#include<cstdio>
#include<algorithm>
#include<cstring>

using namespace std;

long long f[12][1<<11],H,L;
bool legal[1<<11];

bool check(int x)
{
    //0表示待扩展状态  1表示结束状态
    for(int i=1;i<(1<<H);i=i<<1)
        if(x&i)
        {
            if(i<<1<(1<<H) && x&(i<<1)) i=i<<1;
            else return 0;
        }
    return 1;
}

void DP()
{
    memset(f,0,sizeof(f));
    memset(legal,0,sizeof(legal));

    for(int i=0;i<(1<<H);i++)
        if(check(i)) {f[1][i]=1; legal[i]=1;}

    for(int i=2;i<=L;i++)//枚举列
        for(int j=0;j<(1<<H);j++)//枚举上一列状态
            if(f[i-1][j])
                for(int k=0;k<(1<<H);k++)//枚举当前列状态
                    if(legal[j&k] && (j|k)==(1<<H)-1) f[i][k]+=f[i-1][j];
    printf("%lld\n",f[L][(1<<H)-1]);
}

int main()
{
    while(scanf("%lld%lld",&H,&L)==2)
    {
        if(H>L) swap(H,L);//交换一下保证H<L 可以提高效率
        DP();
    }

    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值