SDUT ACM 2619 地板砖 状态压缩启蒙题。。

 

地板砖

Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^

题目描述

利用假期时间,豆豆找个了临时工,帮有钱人家贴地板砖,假设房子的形状为 N x M 矩形,每个地板砖的大小为 1 x 1,且只有黑白两种颜色,这家人很奇怪,他们不喜欢房间中任何一个 2 x 2 的局部区域的 块地板砖的颜色一样。如果出现这种图案,豆豆就要重新贴,这当然难不倒豆豆,但爱学习的豆豆,想知道满足要求的法一共用多少种。

如下图所示:Figure 1.为满足要求的贴法,Figure 2.为不满足要求的贴法

输入

 

输入包含多组测试数据,对于每组测试数据:

输入只有两个正整数 NM(N  500, M  5),分别代表房间的长度和宽度。

输出

 

对于每组测试数据,输出满足要求的贴法总数,由于答案可能很大,所以需要对10007取余。

示例输入

2 2
3 3

示例输出

14
322

提示

 

来源

 “师创杯”山东理工大学第五届ACM程序设计竞赛
 
 
#include <stdio.h>
#include <string.h>
int dp[510][1<<5], n, m;
const int MOD = 10007;
bool check(int x, int y)
{
    int a, b, c, d;
    for(int i = 0; i < m-1; i++)
    {
        a = x & (1<<i);
        b = y & (1<<i);
        c = x & (1<<i+1);
        d = y & (1<<i+1);
        if((a && b && c && d) || (!a && !b && !c && !d))
            return 0;
    }
    return 1;
}
int main()
{
    while(scanf("%d %d", &n, &m) != EOF)
    {
        memset(dp, 0, sizeof(dp));
        for(int i = 0; i < 1<<m; i++)
            dp[1][i] = 1;
        for(int i = 2; i <= n; i++)
            for(int j = 0; j < 1<<m; j++)
                for(int k = 0; k < 1<<m; k++)
                    if(check(j, k))
                        dp[i][j] = (dp[i][j] + dp[i-1][k]) % MOD;
        int ans = 0;
        for(int i = 0; i < 1<<m; i++)
            ans = (ans + dp[n][i]) % MOD;
        printf("%d\n", ans);
    }
    return 0;
}

 

posted @ 2013-05-15 17:27  Anti-Magic  阅读(242)  评论(0编辑  收藏  举报