http://poj.org/problem?id=2411
下次还是去学习下dfs的写法吧 自己乱写的好像有点乱 乱七八糟改了一通过了
以1 1 表示横着的 1 0 表示竖着的 枚举每一行的状态 再枚举前一行的状态判断是否可以同存
注意最后一行要特殊判断一下 0夹着着的1必须为偶数

1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 using namespace std; 7 #define N 3010 8 #define LL __int64 9 LL dp[15][N],o[2][N],k[15]; 10 int main() 11 { 12 int i,j,n,m,e,g; 13 while(scanf("%d%d",&n,&m)!=EOF) 14 { 15 if(n==0&&m==0) 16 break; 17 memset(dp,0,sizeof(dp)); 18 memset(k,0,sizeof(k)); 19 memset(o,0,sizeof(o)); 20 if(n%2!=0&&m%2!=0) 21 { 22 printf("0 "); 23 continue; 24 } 25 o[0][1] = (1<<m)-1; 26 dp[1][o[0][1]] = 1; 27 k[1] = 1; 28 for(i = 2; i <= n ; i++) 29 { 30 for(j = 0 ; j < 1<<m ; j++) 31 { 32 for(g = 1 ; g <= k[i-1] ; g++) 33 { 34 LL gg = o[(i+2)%2][g]; 35 int kk = 0; 36 for(e = 0 ; e < m ; e++) 37 { 38 if((j&(1<<e))==0&&(gg&(1<<e))==0) 39 break; 40 if((j&(1<<e))!=0&&(gg&(1<<e))!=0) 41 kk++; 42 else 43 if(kk%2!=0) break; 44 else kk=0; 45 } 46 if(kk%2==0&&e==m) 47 dp[i][j]+=dp[i-1][gg]; 48 } 49 if(dp[i][j]) 50 { 51 k[i]++; 52 o[(i+1)%2][k[i]] = j; 53 } 54 } 55 } 56 LL ans=0; 57 for(i = 0 ; i < 1<<m ; i++) 58 { 59 if(dp[n][i]==0) 60 continue; 61 int kk=0; 62 for(e = 0 ; e < m ; e++) 63 { 64 if((i&(1<<e))==0&&(kk%2)!=0) 65 break; 66 if((i&(1<<e))==0&&(kk%2)==0) 67 kk = 0; 68 if((i&(1<<e))!=0) 69 kk++; 70 } 71 if(kk%2==0&&e==m) 72 ans+=dp[n][i]; 73 } 74 printf("%I64d ",ans); 75 } 76 return 0; 77 }