TOJ 2850 Corn Fields 状压dp

Source: http://acm.tju.edu.cn/toj/showp.php?pid=2850

题意:n*m的土地上种东西,每个位置分为可以种和不能,种的方案要求不能相邻地种,问合法方案数。(写得有点乱)

分析:做过炮兵阵地,这题就是秒杀了。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 const int mo = 100000000;
 7 int n, m, size, maxl;
 8 int map[15][15];
 9 int s[10000];
10 int dp[15][10000];
11 void dfs()
12 {
13     size = 0;
14     maxl = 1 << m;
15     for (int i = 0; i < maxl; i++)
16         if ((i & (i << 1)) == 0) s[size++] = i;
17 }
18 bool ok(int row, int id)
19 {
20     int x = s[id], tmp;
21     for (int i = m; i > 0; i--){
22         tmp = x % 2;
23         if (tmp == 1 && map[row][i] == 0) return false;
24         x /= 2;
25     }
26     return true;
27 }
28 int main()
29 {
30     while(scanf("%d %d", &n, &m) != EOF)
31     {
32         for (int i = 1; i <= n; i++)
33             for (int j = 1; j <= m; j++)
34                 scanf("%d", &map[i][j]);
35         memset(dp, 0, sizeof(dp));
36         dp[0][0] = 1;
37         dfs();
38         for (int i = 1; i <= n; i++){
39             for (int j = 0; j < size; j++){
40                 if (ok(i, j)){
41                     for (int k = 0; k < size; k++)
42                         if ((s[k] & s[j]) == 0) dp[i][j] = (dp[i][j] + dp[i-1][k]) % mo;
43                 }
44             }
45         }
46         int ans = 0;
47         for (int i = 0; i < size; i++) ans = (ans + dp[n][i]) % mo;
48         printf("%d\n", ans);
49     }
50     return 0;
51 }

 

posted @ 2014-09-06 21:22  james47  阅读(162)  评论(0编辑  收藏  举报