题目链接
题目大意
有一个n * m的格子,铺满1 * 2的地砖有多少种方式
解题思路
是个状压dp的板子题
一个是穷举的状压dp,一个是轮廓线dp
存一下这两个博客讲的还是很详细的
状压版
轮廓线版
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
long long dp[12][1<<12];
int alls,n,m;
int F1(int sta)
{
int i=0;
while(i<m)
{
if(sta&(1<<i))
{
if(i==m-1)
return 0;
else if(sta&(1<<(i+1)))
i+=2;
else
return 0;
}
else
i++;
}
return 1;
}
int Fij(int sta1,int sta2)//sta1当前行,sta2上一行
{
int i=0;
while(i<m)
{
if((sta1&(1<<i))==0)
{
if(sta2&(1<<i))
i++;
else
return 0;
}
else
{
if(sta2&(1<<i))
{
if(i==m-1||!((sta1&(1<<(i+1)))&&(sta2&(1<<(i+1)))))
return 0;
else
i+=2;
}
else
i++;
}
}
return 1;
}
int main()
{
while(~scanf("%d %d",&n,&m))
{
if(n==0&&m==0)
break;
if((n%2)&&(m%2))
{
printf("0\n");
continue;
}
if(n<m)
swap(n,m);
alls=1<<m;
memset(dp,0,sizeof(dp));
for(int i=0; i<alls; i++)
{
if(F1(i))
dp[1][i]=1;
}
for(int k=2; k<=n; k++)
{
for(int i=0; i<alls; i++)
{
for(int j=0; j<alls; j++)
{
if(Fij(i,j))
dp[k][i]+=dp[k-1][j];
}
}
}
printf("%lld\n",dp[n][alls-1]);
}
return 0;
}