题目大意:给你一个n*m的矩形,里面有些格子可以选取。。在可选取选取格子,要求不能相邻。。求方案数。。
思路:状态压缩dp
f[i][j]表示第i行状态为J的方案数
f[i][j] = sigma(f[i - 1][k]) 状态k表示的取法与j取的不相邻。且j为合法取法(与给定的不冲突)
1 /* 2 Time:2013-03-19 23:07:07 3 State:Accepted 4 */ 5 #include <iostream> 6 #include <cstring> 7 #include <cstdlib> 8 #include <cstdio> 9 #include <cmath> 10 #include <string> 11 #include <algorithm> 12 using namespace std; 13 int n, m , map[25] , tot(0), a[1000] , maxnum; 14 int f[15][1 << 14]; 15 void init(){ 16 int x; 17 scanf("%d%d", &n ,&m); 18 for (int i = 1; i <= n; ++i) 19 for (int j = 0; j < m; ++j){ 20 scanf("%d",&x); 21 map[i] = map[i] | (x << j); 22 } 23 } 24 25 void work_opt(int i , int opt){ 26 if (i > m){ 27 a[++tot] = opt; 28 return; 29 } 30 work_opt(i + 1, opt); 31 work_opt(i + 2, opt | (1 << i - 1)); 32 } 33 34 void dp(){ 35 int opt; 36 work_opt(1,0); 37 f[0][0] = 1; 38 for (int i = 1; i <= n; ++i) 39 for (int j = 1; j <= tot; ++j){ 40 opt = map[i] & a[j]; 41 if (opt != a[j]) continue; 42 for (int k = 1; k <= tot; ++k) 43 if ((opt & a[k]) == 0) f[i][opt] = (f[i][opt] + f[i-1][a[k]])% 100000000; 44 } 45 int ans = 0; 46 /* for (int i = 1; i <= tot; ++i) 47 printf("a[%d] = %d\n",i , a[i]); 48 for (int i = 1; i <= n; ++i) 49 for (int j = 1 ; j <= tot; ++j) 50 printf("f[%d][%d] = %d\n", i, a[j], f[i][a[j]]);*/ 51 for (int i = 1; i <= tot; ++i) 52 ans = (ans + f[n][a[i]]) % 100000000; 53 printf("%d\n", ans); 54 } 55 56 int main(){ 57 freopen("poj3254.in","r",stdin); 58 freopen("poj3254.out","w",stdout); 59 init(); 60 dp(); 61 fclose(stdin); fclose(stdout); 62 }