题意:将一个n*m的大矩形,用1*2的小矩形填满,问有多少种方案
思路:状态压缩dp,状态中,0表示当前位没有被填充,1表示当前位被填充。由于第i层的状态只收到第i-1层状态的影响,故而可以对于第i-1层的每个状态,推导第i层的状态。若i-1层的j位置没有被填充,那么第i层必然要竖着放一个矩形。这样,i-1层状态按位取反后,得到第i层竖着放矩形的情况。横着放的情况逐个搜索。
#include<iostream>
#include<cstring>
using namespace std;
__int64 f[20][1<<13],i,j,n,m,num;
void work(int i,int s,int j)
{
if (j==m)
{
f[i][s]+=num;
return;
}
work(i,s,j+1);
if (j<=m-2 && !(s&1<<j) && !(s&1<<j+1))
work(i,s|1<<j|1<<j+1,j+2);
}
int main()
{
while(cin>>n>>m && n!=0)
{
num=1;
memset(f,0,sizeof(f));
work(1,0,0);
for(i=2;i<=n;i++)
for(j=0;j<1<<m;j++)
if(f[i-1][j])
{
num=f[i-1][j];
work(i,~j&((1<<m)-1),0);
}
cout<<f[n][(1<<m)-1]<<endl;
}
return 0;
}