POJ 3254 Corn Fields(状态压缩DP)
看的这个博客,讲的很好,初学状态压缩,对位运算操作还不是很熟,有很多用法,然后就是这个题,开始想用队列优化一下,存上一层合法情况的下标的,老是RE不知为何。。改成暴力的找,居然0ms就过了,这让我情何以堪啊。。。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath> 6 #include <map> 7 #include <queue> 8 #include <set> 9 #include <vector> 10 #define MOD 100000000 11 #define LL __int64 12 using namespace std; 13 int dp[15][16000],p[15][15],bin[15],o[15]; 14 int main() 15 { 16 int i,j,n,m,num,k,ans; 17 scanf("%d%d",&n,&m); 18 o[1] = 1; 19 for(i = 2; i <= 14; i ++) 20 { 21 o[i] = 2*o[i-1]; 22 } 23 for(i = 1; i <= n; i ++) 24 { 25 bin[i] = 0; 26 for(j = 1; j <= m; j ++) 27 { 28 scanf("%d",&p[i][j]); 29 if(!p[i][j])//0表示有草,1表示没草 30 bin[i] += o[j]; 31 } 32 } 33 for(i = 0; i < (1<<m); i ++)//1表示有牛,0表示没有牛 34 { 35 if((i>>1)&i || (i<<1)&i)//用&来快速判断是否有有相邻的1 36 continue; 37 if(i&bin[1])//判断牛必须在草上, 38 continue; 39 dp[1][i] = 1; 40 } 41 for(i = 2; i <= n; i ++) 42 { 43 num = 1; 44 for(j = 0; j < (1<<m); j ++) 45 { 46 if((j>>1)&j || (j<<1)&j) 47 continue; 48 if(j&bin[i]) 49 continue; 50 for(k = 0; k < (1<<m); k ++) 51 { 52 if((k>>1)&k || (k<<1)&k) 53 continue; 54 if(k&bin[i-1]) 55 continue; 56 if(!(j&k)) 57 { 58 dp[i][j] = (dp[i][j] + dp[i-1][k])%MOD; 59 } 60 } 61 } 62 } 63 /*for(i = 1;i <= n;i ++) 64 { 65 for(j = 0;j < (1<<m);j ++) 66 { 67 printf("%d ",dp[i][j]); 68 } 69 printf("\n"); 70 }*/ 71 ans = 0; 72 for(j = 0; j < (1<<m); j ++) 73 ans = (ans+dp[n][j])%MOD; 74 printf("%d\n",ans); 75 return 0; 76 }