题目链接:HDU 1992 Tiling a Grid With Dominoes
题意:一个4*N的矩形,用1*2的小矩形铺满的方法数是多少。
思路:4*N。只有4行想到状压,dp[i][j]表示前i行状态j的方法数,影响当前行的只有上一行!0成对出现表示横着放,1表示竖着放,所以第一行的状态0.3.9.12.15五种,并且只要上一行是0状态。当前行的状态就为0.3.9.12.15五种可能。还有当前行s1和上一行s2匹配仅当s1==0 || s1==(s2取反),特别注意上一行状态是0110(6)时只有1001(9)和其匹配。答案不超int。n最大22~
AC代码:
#include <stdio.h>
#include <string.h>
#include <vector>
int dp[30][20]; // 前i行状态j的方法数
bool ok(int pres,int nxts){
int tmp;
tmp=pres^15;
//注意
if(pres==6){
if(nxts==9)
return true;
return false;
}
if(nxts==0 || nxts==tmp)
return true;
return false;
}
int main()
{
int cas=1;
int t,n,i,j,k;
scanf("%d",&t);
while(t--){
memset(dp,0,sizeof dp);
scanf("%d",&n);
for(i=0;i<n;i++){
if(i==0){
for(j=0;j<16;j++){
if(j==0 || j==3 || j==9 || j==12 || j==15){
dp[i][j]=1;
}
}
}else{
//j上一行状态,k这一行状态
for(j=0;j<16;j++){
if(!dp[i-1][j])
continue;
if(j==0){
for(k=0;k<16;k++){
if(k==0 || k==3 || k==9 || k==12 || k==15){
//printf("%d -> %d (%d)\n",j,k,dp[i-1][j]);
dp[i][k]+=dp[i-1][j];
}
}
}else{
for(k=0;k<16;k++){
if(ok(j,k)){
//printf("%d -> %d (%d)\n",j,k,dp[i-1][j]);
dp[i][k]+=dp[i-1][j];
}
}
}
}
}
}
printf("%d %d\n",cas++,dp[n-1][0]);
}
return 0;
}