SDUT ACM 2619 地板砖 状态压缩启蒙题。。
地板砖
Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^
题目描述
利用假期时间,豆豆找个了临时工,帮有钱人家贴地板砖,假设房子的形状为 N x M 的矩形,每个地板砖的大小为 1 x 1,且只有黑白两种颜色,这家人很奇怪,他们不喜欢房间中任何一个 2 x 2 的局部区域的 4 块地板砖的颜色一样。如果出现这种图案,豆豆就要重新贴,这当然难不倒豆豆,但爱学习的豆豆,想知道满足要求的贴法一共用多少种。
如下图所示:Figure 1.为满足要求的贴法,Figure 2.为不满足要求的贴法
输入
输入包含多组测试数据,对于每组测试数据:
输入只有两个正整数 N、M(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; }