题目链接:http://poj.org/problem?id=2411
搜索到众多题解,有的过于简单看不懂,有的冗杂看着烦,经过挑选 这篇(这里有个链接) 还是蛮不错的。
题解中 s 和 ss 兼容是指:能不能通过一种方式,把第 i-1 行空余的方格填满的同时让第 i 行达到状态 s 。
代码是抄的题解的,具体的注释还是看题解吧
#include<iostream>
#include<memory.h>
using namespace std;
long long dp[13][1<<13];
long long ans[13][13];
int n,m;
bool init(int s)
{
for (int k=0; k<m;)
{
if (s & (1<<k))
{
if (k == m-1) return false;
if (s & (1<<(k+1))) k+=2;
else return false;
}
else k++;
}
return true;
}
bool ok(int s, int ss)
{
for (int j=0; j<m;)
if (s & (1<<j))
{
if (ss & (1<<j))
{
if (j == m-1 || (s&(1<<(j+1)))==0 || (ss&(1<<(j+1)))==0 ) return false;
else j+=2;
}
else j++;
}
else
{
if (ss & (1<<j)) j++;
else return false;
}
return true;
}
int main()
{
memset(ans,-1,sizeof(ans));
while (cin>>n>>m && n && m)
{
if (n < m) swap(n,m);
if (!ans[n][m])
{
cout<<ans[n][m]<<endl;
continue;
}
if (n & 1 && m & 1)
{
ans[n][m] = ans[m][n] = 0;
cout<<0<<endl;
continue;
}
memset(dp,0,sizeof(dp));
for (int s=0; s<(1<<m)-1; s++)
if (init(s))
dp[1][s] = 1;
for (int i=2; i<=n; i++)
for (int s=0; s<=(1<<m)-1; s++)
for (int ss=0; ss<=(1<<m)-1; ss++)
if (ok(s, ss))
dp[i][s] += dp[i-1][ss];
ans[n][m] = ans[m][n] = dp[n][(1<<m)-1];
cout<<ans[n][m]<<endl;
}
return 0;
}