题意:在n*m的方格里铺1*2的骨牌,有多少种方案
/* 第一次做插头DP,感觉和状压差不多。 这道题是利用上一行的状态来更新下一行的状态。 1代表上一行这个位置填了一个竖的(即本行可以填); 0代表填了一个横的或者是竖的方格的第二行(即本行可以填)。 */ #include<cstdio> #include<iostream> #include<cstring> #define N 12 using namespace std; int n,m; long long dp[N][1<<N]; void dfs(int s,int ss,int y,int x){ if(y>m-1){ dp[x+1][ss]+=dp[x][s]; return; } if(s&(1<<y)){//如果x行y列填的是竖的,那么x+1行y列就没法填 dfs(s,ss,y+1,x); return; } dfs(s,ss|(1<<y),y+1,x);//填一个竖的 if(y<=m-2&&!(s&(1<<y+1)))//如果x+1行y+1列可以填,那就可以在y列填一个横的 dfs(s,ss,y+2,x); } int main(){ while(scanf("%d%d",&n,&m)&&n&&m){ if((n*m)&1){ printf("0 "); continue; } if(n==1||m==1){ printf("1 "); continue; } if(n<m) swap(n,m); memset(dp,0,sizeof(dp)); dp[0][0]=1; for(int i=0;i<n;i++) for(int j=0;j<(1<<m);j++){ if(!dp[i][j]) continue; dfs(j,0,0,i); } cout<<dp[n][0]<<endl; } return 0; }