状态压缩dp/sgu 131 Hardwood floor
题意
给出一个n*m的格子,要求用1*2的块和2*2缺一角的块填满,求方案数
分析
状压dp,以下来自nocow:
状态压缩DP,转移的时候情况很多,要一个个写出来理清楚再写。 一行一行推,opt1为上一行的状态,opt2为当前行的状态,u1,u2分别为上下两行是否与左边相连而凸出来。
/*
Case 1 2 3 4 5 6 7
| +- | L or U L| or U| -+ or -+ L or U or L or U
| | +- -- -- -+ -+ W| L| W W L L
old L : connect with Left block
U : connect with Upper block
new - | + : describe the shape of forms
empty W : NO put this block, wait for the forms of next row
*/
Accepted Code
1 /* 2 PROBLEM:sgu131 3 AUTHER:Rinyo 4 MEMO:状态压缩dp 5 */ 6 7 #include<cstdio> 8 long long f[10][512]; 9 int n,m,i; 10 11 void dfs(int j,int s1,int s2,int u1,int u2) 12 { 13 if (j==m) 14 { 15 if (u1==0 && u2==0) f[i+1][s2]+=f[i][s1]; 16 return; 17 } 18 if (u2==0) 19 { 20 if (u1==0) 21 { 22 dfs(j+1,s1<<1,(s2<<1)+1,0,0); 23 dfs(j+1,s1<<1,(s2<<1)+1,1,0); 24 dfs(j+1,s1<<1,(s2<<1)+1,0,1); 25 } 26 dfs(j+1,(s1<<1)+1-u1,(s2<<1)+1,0,1); 27 dfs(j+1,(s1<<1)+1-u1,(s2<<1)+1,1,1); 28 } 29 if (u1==0) dfs(j+1,(s1<<1),(s2<<1)+u2,1,1); 30 dfs(j+1,(s1<<1)+1-u1,(s2<<1)+u2,0,0); 31 } 32 33 34 int main() 35 { 36 scanf("%d%d",&n,&m); 37 if (n<m) {int t=n;n=m;m=t;} 38 f[0][(1<<m)-1]=1; 39 for (i=0;i<n;i++) dfs(0,0,0,0,0); 40 printf("%I64d",f[n][(1<<m)-1]); 41 return 0; 42 }