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 ",maxz); 57 } 58 return 0; 59 }