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

 

posted @ 2013-08-16 22:45  _雨  阅读(179)  评论(0编辑  收藏  举报