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 }