Find the number of ways to tile an m*n rectangle with long dominoes -- 3*1 rectangles.
Each domino must be completely within the rectangle, dominoes must not overlap (of course, they may touch each other), each point of the rectangle must be covered.
The input contains several cases. Each case stands two integers m and n (1 <= m <= 9, 1 <= n <= 30) in a single line. The input ends up with a case of m = n = 0.
<p< dd="">
Output the number of ways to tile an m*n rectangle with long dominoes.
<p< dd="">
3 3 3 10 0 0
<p< dd="">
2 28
思路:这道题类似于之前的1*2的摆放的问题
区别就是需要搜索时需要判定三个状态,现在的,下一个的,下下一个的
代码如下:#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #include<string> using namespace std; const int mx=1<<9; int n,m,ans,k,T; long long dp[31][mx][mx]; void dfs(int i,int j,int now,int nex,int next,long long sum) { if(j==m)//搜到了i列最后一行 { dp[i+1][nex][next]+=sum;//直接用sum防止本次枚举的这一种情况影响本次枚举的另一种情况 return ; } if(now&1<<j)//如果j行放了东西 dfs(i,j+1,now,nex,next,sum);//就搜下一行 if(!(now&1<<j)&&!(nex&1<<j)&&!(next&1<<j)) dfs(i,j+1,now,nex|1<<j,next|1<<j,sum);//放一个1*3的,对后面两lie都有影响 if((j+2<m)&&!(now&1<<j)&&!(now&1<<(j+1))&&!(now&1<<(j+2))) dfs(i,j+3,now,nex,next,sum);//连续三个位置都没放木块,可以放一个3*1的 } int main() { int t,j,k,l,q,x,y,ss,h; int cas=1,flag,f1; while(scanf("%d%d",&m,&n)) { if(m==0&&n==0) break; memset(dp,0,sizeof(dp)); ans=0; dp[0][0][0]=1; for(int i=0;i<n;i++) { for(int j=0;j<1<<m;j++) { for(int k=0;k<1<<m;k++) if (dp[i][j][k]) dfs(i,0,j,k,0,dp[i][j][k]); } } printf("%lld\n",dp[n][0][0]); } return 0; }