传送门:http://poj.org/problem?id=2411
思路:分成当前格①不放②左放③上放三种情况转移 当前状态是从当前格子上面开始计的,不是从左到右,是先从上到下再从左到右。
代码:
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
#include<iostream>
#include<map>
#include<vector>
#include<set>
#include<queue>
using namespace std;
typedef long long ll;
ll dp[2][1<<11];
ll n,m;
int main()
{
std::ios::sync_with_stdio(false);
while(cin>>n>>m,n,m)
{
memset(dp,0,sizeof(dp));
ll cur=0;
ll x=1<<(m-1);
dp[cur][(1<<m)-1]=1;
for(ll i=1;i<=n;i++)
{
for(ll j=1;j<=m;j++)
{
cur^=1;
memset(dp[cur],0,sizeof(dp[cur]));
for(ll k=0;k<(1<<m);k++)
{
if(k&x)
{
dp[cur][(k^x)<<1]+=dp[1-cur][k];//不放
if(j!=1&&!(k&1))
{
dp[cur][((k^x)<<1)|3]+=dp[1-cur][k];//左放
}
}
else if(i!=1)
{
dp[cur][((k&(x-1))<<1)|1]+=dp[1-cur][k];//上放
}
}
}
}
cout<<dp[cur][(1<<m)-1]<<endl;
}
return 0;
}