题目:http://poj.org/problem?id=2411
状态压缩,一行的状态记为一个二进制数,从上往下逐行DP,答案输出最后一行填0的方案数。
代码如下:
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> using namespace std; int h,w,s[2050],ts,up; long long f[15][2050]; void init(int up) { ts=0; for(int i=0;i<=up;i++) { int r,k=0,x=i,t=0; bool flag=0; while(t<w) { r=x%2; if(r) { if(k%2==1) { flag=1; break; } else k=0; } else k++; x/=2; t++; } if(!flag&&(k%2)==0)s[++ts]=i; } return; } int main() { while(scanf("%d%d",&h,&w)==2) { if(!h&&!w)return 0; if(h==1) { if(w%2==0)printf("1 "); else printf("0 "); continue; } memset(f,0,sizeof f); up=(1<<w)-1; init(up); for(int j=1;j<=ts;j++)f[1][s[j]]++;// for(int i=2;i<=h;i++) for(int j=0;j<=up;j++) for(int k=0;k<=up;k++) if(!(j&k)) { int tmp=(j|k); bool flag=0; for(int l=1;l<=ts;l++) if(tmp==s[l]){flag=1;break;} if(flag)f[i][k]+=f[i-1][j]; } printf("%lld ",f[h][0]);//0! } return 0; }