題目鏈接: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;
}