poj3254Corn Fields(状压)

http://poj.org/problem?id=3254

第一个状压题 思路挺好想 用二进制表示每行的状态 然后递推

用左移 右移来判断是不是01间隔出现 c大神教的 我的代码WA在这个地方了。。

改了点 就A了

 1 #include <iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 #include<stdlib.h>

 5 #include<algorithm>

 6 using namespace std;

 7 #define mod 100000000

 8 #define LL long long

 9 int a[15][15];

10 LL dp[15][5050],s[15],num[2][5050],k[15],pp[15];

11 int main()

12 {

13     int i,j,n,m,g;

14     while(scanf("%d%d",&n,&m)!=EOF)

15     {

16         memset(dp,0,sizeof(dp));

17         memset(k,0,sizeof(k));

18         pp[0] = 1;

19         for(i = 1; i <= 15 ; i++)

20         pp[i] = pp[i-1]*2;

21         for(i = 1; i <= n ;i++)

22         {

23             s[i] = 0;

24              for(j = 1 ;j <=m ;j++)

25              {

26                  scanf("%d",&a[i][j]);

27                  s[i]+=pp[j-1]*a[i][j];

28              }

29         }

30         for(i = 0; i < 1<<m ; i++)

31         if((((i>>1)&(i))==0||((i<<1)&(i))==0)&((i&s[1])==i))

32         {

33             dp[1][i]++;

34             num[0][++k[1]] = i;

35         }

36         for(i = 2;i <= n ;i++)

37         {

38             for(j = 0; j < 1<<m ; j++)

39             {

40                 if((((j>>1)&(j))==0||(((j<<1)&(j))==0))&&((j&s[i])==j))

41                 {

42                     k[i]++;

43                     for(g = 1 ; g <= k[i-1] ; g++)

44                     {

45                         int o = num[i%2][g];

46                         if((j&o)==0)

47                         dp[i][j]=(dp[i][j]+dp[i-1][o])%mod;

48                     }

49                     num[(i+1)%2][k[i]] = j;

50                 }

51             }

52         }

53         LL maxz=0;

54         for(i = 0 ; i < 1<<m ; i++)

55         maxz = (maxz+dp[n][i])%mod;

56         printf("%d\n",maxz);

57     }

58     return 0;

59 }
View Code

 

你可能感兴趣的:(Field)