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

 

你可能感兴趣的:(poj)