農場主\(John\)新買了一塊長方形的新牧場,這塊牧場被劃分紅\(M\)行\(N\)列\((1 ≤ M ≤ 12; 1 ≤ N ≤ 12)\),每一格都是一塊正方形的土地。John打算在牧場上的某幾格裏種上美味的草,供他的奶牛們享用。數組
遺憾的是,有些土地至關貧瘠,不能用來種草。而且,奶牛們喜歡獨佔一塊草地的感受,因而\(John\)不會選擇兩塊相鄰的土地,也就是說,沒有哪兩塊草地有公共邊。spa
\(John\)想知道,若是不考慮草地的總塊數,那麼,一共有多少種種植方案可供他選擇?(固然,把新牧場徹底荒廢也是一種方案)code
輸入格式:io
第一行:兩個整數\(M\)和\(N\),用空格隔開。class
第\(2\)到第\(M+1\)行:每行包含\(N\)個用空格隔開的整數,描述了每塊土地的狀態。第\(i+1\)行描述了第\(i\)行的土地,全部整數均爲\(0\)或\(1\),是\(1\)的話,表示這塊土地足夠肥沃,\(0\)則表示這塊土地不適合種草。map
輸出格式:二進制
一個整數,即牧場分配總方案數除以\(100,000,000\)的餘數。di
輸入樣例#1:co
2 3 1 1 1 0 1 0
輸出樣例#1:math
9
思路:\(f[i][j]\)表示第\(i\)行爲\(j\)狀態時的方案數,\(F[i]\)表示第\(i\)行的土地狀況,\(state\)數組爲預先處理好的全部狀態。而後狀態轉移的時候要判斷當前狀態是否合法,還有用二進制運算判斷四個方向是否有衝突的牛,而後進行狀態轉移。
代碼:
/* f[i][j]表示第i行爲j狀態時的方案數,F[i]表示第i行的土地狀況,state數組爲預先處理好的全部狀態。 */ #include<cstdio> const int mod=1e8; int ans,map[13][13],m,n,F[13],f[13][4097]; bool state[4097]; int main() { scanf("%d%d",&m,&n); int maxn=1<<n; for(int i=1;i<=m;++i) { for(int j=1;j<=n;++j) { scanf("%d",&map[i][j]); F[i]=(F[i]<<1)+map[i][j]; } } for(int i=0;i<maxn;++i) state[i]=(!(i&(i<<1))); f[0][0]=1; for(int i=1;i<=m;++i) { for(int j=0;j<maxn;++j) { if((F[i]&j)==j&&state[j]) { for(int k=0;k<maxn;++k) { if((k&j)==0) f[i][j]=(f[i][j]+f[i-1][k])%mod; } } } } for(int i=0;i<maxn;++i) ans=(ans+f[m][i])%mod; printf("%d\n",ans); return 0; }