您的位置:首页 > 其它

棋盘覆盖2(1X2骨牌 和 L型骨牌 混合铺满)(强行轮廓线DP)

2016-08-17 18:36 274 查看
NYOJ435【题意】用1*2或者L型的地板铺满n*m的地面一共有多少中方案

因为多了L型骨牌,轮廓线需要判断左上方的填充情况,所以轮廓线的状态要加一位,最高位表示左上方,次高位表示上方,最低位表示左方。

状态的转移也复杂些,之前是上方有空就必填,否则没机会填了,现在因为可以填充到左上方的格子,所以上方有空也可以考虑不填,但是当当前位置是每排的最后一个时上方的格子不填就没机会 填了,所以这里要做个特判。然后左上方为空是必填的。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;

#define LL long long int

inline int read()
{
char ch;
int ans;
ch = getchar();
if (ch == -1)
return -1;
while (ch < '0' || ch > '9')
ch = getchar();
ans = ch - '0';
while ((ch = getchar()) >= '0' && ch <= '9')
{
ans = ans * 10 + ch - '0';
}
return ans;
}

LL dp[2][1 << 10];

int main()
{
int n, m;
while (~scanf("%d %d", &n, &m))
{
if (n < m)
{
int t = m;
m = n;
n = t;
}
int h = 1 << (m - 1);
int hh = 1 << (m);
memset(dp, 0, sizeof(dp));
int cur = 0;
dp[0][(hh << 1) - 1] = 1;
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < m; ++j)
{
cur ^= 1;
memset(dp[cur], 0, sizeof(dp[cur]));
for (int k = 0; k < (hh << 1); ++k)
{
if (i && j && !(k & hh))//左上方没填,不能不填
{
if (!(k & h))
dp[cur][(k << 1) | hh | 1] += dp[cur ^ 1][k];//缺左下角
if (!(k & 1))
{
if ((k & h) || j != m - 1)
dp[cur][(k << 1) | 3] += dp[cur ^ 1][k];//缺右上角
if (!(k & h))
dp[cur][(k << 1) | hh | 2] += dp[cur ^ 1][k];//缺右下角
}
}
if (i && j && (k & hh))//左上方填了,可以不填
{
if (!(k & 1))
{
if ((k & h) || j != m - 1)
dp[cur][((k^hh) << 1) | 3] += dp[cur ^ 1][k];//横放
}
if (!(k & h))
{
dp[cur][((k^hh) << 1) | hh | 1] += dp[cur ^ 1][k];//竖放
if (!(k & 1))
dp[cur][((k^hh) << 1) | hh | 3] += dp[cur ^ 1][k];//缺左上角
}
if ((k & h) || j != m - 1)
dp[cur][((k^hh) << 1)] += dp[cur ^ 1][k];//不放
}
if (!i && j)
{
if (!(k & 1))
dp[cur][((k&(hh - 1)) << 1) | 3] += dp[cur ^ 1][k];//横放
dp[cur][((k&(hh - 1)) << 1)] += dp[cur ^ 1][k];//不放
}
else if (i && !j)
{
if (!(k & h))
dp[cur][((k&(hh - 1)) << 1) | hh | 1] += dp[cur ^ 1][k];//竖放
if ((k&h) || j !
9943
= m - 1)
dp[cur][((k&(hh - 1)) << 1)] += dp[cur ^ 1][k];//不放
}
else if (!i && !j)
{
dp[cur][((k&(hh - 1)) << 1)] += dp[cur ^ 1][k];//不放
}

}
}
}
printf("%lld\n", dp[cur][(hh << 1) - 1]);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: