poj2411Mondriaan's Dream(状压)

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\n");
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\n",ans);
75     }
76     return 0;
77 }
View Code

 

posted @ 2013-08-17 19:42  _雨  阅读(312)  评论(0编辑  收藏  举报