【插头DP】ZOJ 3466 The Hive II

通道:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3466

题意:六边形,多回路全覆盖,有阻碍。

代码:

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 
  5 using namespace std;
  6 
  7 const int MAX_N = 13;
  8 const int MAX_M = 13;
  9 const int HASH = 1000007;
 10 const int MAX_S = 1000007 + 10; 
 11 
 12 const int mov[20] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30};
 13 
 14 struct node {
 15     int head[HASH], nxt[MAX_S], cnt;
 16     long long dp[MAX_S], st[MAX_S];
 17     void init() {
 18         memset(head, -1, sizeof head);
 19         cnt = 0;
 20     }
 21     void push(long long s, long long v) {
 22         int now = s % HASH; 
 23         for(int i = head[now]; ~i; i = nxt[i]) if(st[i] == s) {
 24             dp[i] += v;
 25             return ;
 26         }
 27         st[cnt] = s;      dp[cnt] = v;
 28         nxt[cnt] = head[now];
 29         head[now] = cnt++;
 30     }
 31 }d[2];
 32 
 33 const int n = 8;
 34 
 35 int m;
 36 int A[MAX_N][MAX_M];
 37 
 38 void blank(int i, int j, int cur) {
 39     for (int k = 0; k < d[cur].cnt; ++k) {
 40         long long v = d[cur].st[k];
 41         if (j == 1) {
 42             if (i % 2 == 1) v >>= 1;
 43             else v <<= 1;
 44         }
 45         int a = v >> mov[m + 1] & 1;
 46         int b = v >> mov[j] & 1;
 47         int c = v >> mov[j] >> 1 & 1;
 48         int left = i % 2 == 1 || j != 1;
 49         int right = i % 2 == 0 || j != m;
 50         int raw = j != m;
 51     
 52         int dd = a + b + c;
 53         if (dd == 3) continue;
 54         if (dd == 0) {
 55             if (left && right) d[cur ^ 1].push(v ^ 3 << mov[j], d[cur].dp[k]);
 56             if (left && raw) d[cur ^ 1].push(v ^ 1 << mov[j] ^ 1 << mov[1 + m], d[cur].dp[k]);
 57             if (right && raw) d[cur ^ 1].push(v ^ 2 << mov[j] ^ 1 << mov[1 + m], d[cur].dp[k]);
 58         } else if (dd == 1) {
 59             if (a) v ^= 1 << mov[m + 1];
 60             else if (b) v ^= 1 << mov[j];
 61             else v ^= 2 << mov[j];
 62             if (left) d[cur ^ 1].push(v ^ 1 << mov[j], d[cur].dp[k]);
 63             if (right) d[cur ^ 1].push(v ^ 2 << mov[j], d[cur].dp[k]);
 64             if (raw) d[cur ^ 1].push(v ^ 1 << mov[m + 1], d[cur].dp[k]);
 65         } else {
 66             if (a) v ^= 1 << mov[m + 1];
 67             if (b) v ^= 1 << mov[j];
 68             if (c) v ^= 2 << mov[j];
 69             d[cur ^ 1].push(v, d[cur].dp[k]);
 70         }
 71     }
 72 }
 73 
 74 void block(int i, int j, int cur) {
 75     for (int k = 0; k < d[cur].cnt; ++k) {
 76         long long v = d[cur].st[k];
 77         if (j == 1) {
 78             if (i % 2 == 1) v >>= 1;
 79             else v <<= 1;
 80         }
 81         int a = v >> mov[m + 1] & 1;
 82         int b = v >> mov[j] & 1;
 83         int c = v >> mov[j] >> 1 & 1;
 84         if (!a && !b && !c) 
 85             d[cur ^ 1].push(v, d[cur].dp[k]);
 86     }
 87 }
 88 
 89 
 90 int main() {
 91     int z = 0;
 92     while (2 == scanf("%d%d", &m, &z)) {
 93         memset(A, 0, sizeof A);
 94         for (int i = 0; i < z; ++i) {
 95             char str[3];
 96             scanf("%s", str);
 97             A[str[1] - 'A' + 1][str[0] - 'A' + 1] = 1;
 98         }
 99         int cur = 0;
100         d[cur].init();
101         d[cur].push(0, 1);
102         for (int i = 1; i <= n; ++i) {
103             for (int j = 1; j <= m; ++j) {
104                 d[cur ^ 1].init();
105                 if (A[i][j]) block(i, j, cur);
106                 else blank(i, j, cur);
107                 cur ^= 1;
108             }
109             //for (int j = 0; j < d[cur].cnt; ++j)
110         //        d[cur].st[j] <<= 2;
111         }
112         long long ans = 0;
113         for (int i = 0; i < d[cur].cnt; ++i) if (d[cur].st[i] == 0)    
114             ans += d[cur].dp[i];
115         printf("%lld\n", ans);
116     }
117     return 0;
118 }
119 
120 /*
121 
122 8 3
123 AE EF FG
124 
125 3 5
126 BB CD BF AH CG
127 
128 3 8
129 BA BB BC BD BE BF BG BH
130 
131 3 6
132 BB BC BD BE BF BG
133 */
View Code

 

posted @ 2015-07-14 21:06  mithrilhan  阅读(182)  评论(0编辑  收藏  举报