1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 #include <iostream> 5 using namespace std; 6 typedef long long LL; 7 8 const int MAXN = 13; 9 10 int mat[MAXN][MAXN]; 11 LL dp[MAXN][MAXN][1 << MAXN]; 12 int n, m, T; 13 14 LL solve() { 15 memset(dp, 0, sizeof(dp)); 16 dp[0][m][0] = 1; 17 for(int i = 1; i <= n; ++i) { 18 for(int j = 0; j < (1 << m); ++j) dp[i][0][j << 1] = dp[i - 1][m][j]; 19 for(int k = 1; k <= m; ++k) { 20 for(int state = 0; state < (1 << (m + 1)); ++state) { 21 int y = 1 << k, x = y >> 1; 22 if(mat[i][k]) { 23 if((state & x) && (state & y)) { 24 dp[i][k][state] = dp[i][k - 1][state - x - y]; 25 } else if((state & x) == 0 && (state & y) == 0) { 26 dp[i][k][state] = dp[i][k - 1][state + x + y]; 27 } else dp[i][k][state] = dp[i][k - 1][state ^ x ^ y] + dp[i][k - 1][state]; 28 } else { 29 if((state & x) == 0 && (state & y) == 0) { 30 dp[i][k][state] = dp[i][k - 1][state]; 31 } else dp[i][k][state] = 0; 32 } 33 } 34 } 35 } 36 return dp[n][m][0]; 37 } 38 39 int main() { 40 scanf("%d", &T); 41 for(int t = 1; t <= T; ++t) { 42 scanf("%d%d", &n, &m); 43 for(int i = 1; i <= n; ++i) 44 for(int j = 1; j <= m; ++j) scanf("%d", &mat[i][j]); 45 printf("Case %d: There are %I64d ways to eat the trees.\n", t, solve()); 46 } 47 }
代码(0MS)(hash)(下面代码是lld的……):
1 #include <iostream> 2 #include <algorithm> 3 #include <cstring> 4 #include <cstdio> 5 using namespace std; 6 typedef long long LL; 7 8 const int MAXH = 20010; 9 const int SIZEH = 13131; 10 11 struct hash_map { 12 int head[SIZEH]; 13 int next[MAXH], state[MAXH]; 14 LL val[MAXH]; 15 int size; 16 17 void init() { 18 memset(head, -1, sizeof(head)); 19 size = 0; 20 } 21 22 void insert(int st, LL sv) { 23 int h = st % SIZEH; 24 for(int p = head[h]; ~p; p = next[p]) { 25 if(state[p] == st) { 26 val[p] += sv; 27 return ; 28 } 29 } 30 state[size] = st; val[size] = sv; next[size] = head[h]; head[h] = size++; 31 } 32 } hashmap[2]; 33 34 int getB(int state, int i) { 35 return (state >> i) & 1; 36 } 37 38 void setB(int &state, int i, int val) { 39 state = (state & ~(1 << i)) | (val << i); 40 } 41 42 int mat[14][14]; 43 int n, m, T; 44 hash_map *cur, *last; 45 46 void update(int state, LL val, int x, int y) { 47 int left = getB(state, y); 48 int up = getB(state, y + 1); 49 if(mat[x][y] == 0) { 50 if(left == 0 && up == 0) cur->insert(state, val); 51 return ; 52 } 53 if(left == 0 && up == 0) { 54 if(x < n - 1 && y < m - 1) { 55 int newState = state; 56 setB(newState, y, 1); 57 setB(newState, y + 1, 1); 58 cur->insert(newState, val); 59 } 60 } else if(left == 0 || up == 0) { 61 if(x < n - 1) { 62 int newState = state; 63 setB(newState, y, 1); 64 setB(newState, y + 1, 0); 65 cur->insert(newState, val); 66 } 67 if(y < m - 1) { 68 int newState = state; 69 setB(newState, y, 0); 70 setB(newState, y + 1, 1); 71 cur->insert(newState, val); 72 } 73 } else { 74 int newState = state; 75 setB(newState, y, 0); 76 setB(newState, y + 1, 0); 77 cur->insert(newState, val); 78 } 79 } 80 81 LL solve() { 82 cur = hashmap, last = hashmap + 1; 83 last->init(); 84 last->insert(0, 1); 85 for(int i = 0; i < n; ++i) { 86 int sz = last->size; 87 for(int k = 0; k < sz; ++k) last->state[k] <<= 1; 88 for(int j = 0; j < m; ++j) { 89 cur->init(); 90 sz = last->size; 91 for(int k = 0; k < sz; ++k) 92 update(last->state[k], last->val[k], i, j); 93 swap(cur, last); 94 } 95 } 96 for(int k = 0; k < last->size; ++k) 97 if(last->state[k] == 0) return last->val[k]; 98 return 0; 99 } 100 101 int main() { 102 scanf("%d", &T); 103 for(int t = 1; t <= T; ++t) { 104 scanf("%d%d", &n, &m); 105 for(int i = 0; i < n; ++i) 106 for(int j = 0; j < m; ++j) scanf("%d", &mat[i][j]); 107 printf("Case %d: There are %lld ways to eat the trees.\n", t, solve()); 108 } 109 }