首页 > 代码库 > TOJ 2850 Corn Fields 状压dp

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 }

 

TOJ 2850 Corn Fields 状压dp