【插头DP】HDU 4285 circuits

通道:http://acm.hdu.edu.cn/showproblem.php?pid=4285

题意:多回路, 有障碍K回路问题。

代码:

  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 = 300007;
 10 const int MAX_S = 1000007 + 10;
 11 const int MOD = 1000000007;
 12 
 13 
 14 const int mov[20] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30};
 15  
 16 struct node {
 17     int head[HASH], nxt[MAX_S];
 18     long long dp[MAX_S], st[MAX_S];
 19     long long num[MAX_S];
 20     int cnt;
 21     void init() {
 22         memset(head, -1, sizeof head);
 23         cnt = 0;
 24     }
 25     void push(long long s, long long v, long long val) {
 26         int now = s % HASH;
 27         for(int i = head[now]; ~i; i = nxt[i]) if(st[i] == s && val == num[i]) {
 28             dp[i] = (dp[i] + v) % MOD;
 29             return ;
 30         }
 31         st[cnt] = s; dp[cnt] = v;  num[cnt] = val;
 32         nxt[cnt] = head[now];
 33         head[now] = cnt++;
 34     }
 35 }d[2];
 36  
 37 int n, m, K;
 38  
 39 int find_pos(long long s, int p) {
 40     return (s >> (p << 1)) & 3;
 41 }
 42  
 43 void tp(long long &s, int p, long long v) {
 44     s &= (~(3ll << (p << 1)));
 45     s |= (v << (p << 1));
 46 }
 47  
 48 int find_r(long long s, int p) {
 49     int cnt = 0;
 50     for(int i = p; i <= m; ++i) {
 51         if(find_pos(s, i) == 1) ++cnt;
 52         else if(find_pos(s, i) == 2) --cnt;
 53         if(!cnt) return i;
 54     }
 55 }
 56  
 57 int find_l(long long s, int p) {
 58     int cnt = 0;
 59     for(int i = p; i >= 0; --i) {
 60         if(find_pos(s, i) == 2) ++cnt;
 61         else if(find_pos(s, i) == 1) --cnt;
 62         if(!cnt) return i;
 63     }
 64 }
 65  
 66 void blank(int i, int j, int cur) {
 67     for(int k = 0; k < d[cur].cnt; ++k) {
 68         long long t = d[cur].st[k];
 69         int l = find_pos(t, j - 1), r = find_pos(t, j);
 70         if(l && r) {
 71             if(l == 1 && r == 1) {
 72                 int tpos = find_r(t, j);
 73                 tp(t, j - 1, 0); tp(t, j, 0); tp(t, tpos, 1);
 74                 d[cur ^ 1].push(t, d[cur].dp[k], d[cur].num[k]);
 75             } else if(l == 2 && r == 1) {
 76                 tp(t, j - 1, 0); tp(t, j, 0);
 77                 d[cur ^ 1].push(t, d[cur].dp[k], d[cur].num[k]);
 78             } else if(l == 2 && r == 2) {
 79                 int tpos = find_l(t, j - 1);
 80                 tp(t, j - 1, 0); tp(t, j, 0); tp(t, tpos, 2);
 81                 d[cur ^ 1].push(t, d[cur].dp[k], d[cur].num[k]);
 82             } else { 
 83                 int count = 0;
 84                 for (int z = j - 2; z >= 0; --z) if (find_pos(t, z)) ++count;
 85                 if (count & 1) continue;
 86                 for (int z = j + 1; z <= m; ++z) if (find_pos(t, z)) ++count;
 87                 if (count & 1) continue;
 88                 tp(t, j - 1, 0); tp(t, j, 0);
 89                  d[cur ^ 1].push(t, d[cur].dp[k], d[cur].num[k] + 1);
 90             }
 91         } else if(l) {
 92             if(i < n) {
 93                 d[cur ^ 1].push(t, d[cur].dp[k], d[cur].num[k]);
 94             }
 95             if(j < m) {
 96                 tp(t, j - 1, 0); tp(t, j, l);
 97                 d[cur ^ 1].push(t, d[cur].dp[k], d[cur].num[k]);
 98             }
 99         } else if(r) {
100             if(j < m) {
101                 d[cur ^ 1].push(t, d[cur].dp[k], d[cur].num[k]);
102             }
103             if(i < n) {
104                 tp(t, j - 1, r); tp(t, j, 0);
105                 d[cur ^ 1].push(t, d[cur].dp[k], d[cur].num[k]);
106             }
107         } else { // 新建
108             if(i < n && j < m) {
109                 tp(t, j - 1, 1); tp(t, j, 2);
110                 d[cur ^ 1].push(t, d[cur].dp[k], d[cur].num[k]);
111             }
112         }
113     }
114 }
115  
116 void block(int i, int j, int cur) {
117     for (int k = 0; k < d[cur].cnt; ++k) {
118         long long t = d[cur].st[k];
119         int l = find_pos(t, j - 1), r = find_pos(t, j);
120         if (!l && !r) d[cur ^ 1].push(t, d[cur].dp[k], d[cur].num[k]);
121     }
122 }
123  
124 char str[17];
125 int a[MAX_N][MAX_M];
126 
127 int main() {
128     int T;
129     scanf("%d", &T);
130     while (T-- > 0) {
131         scanf("%d%d%d", &n, &m, &K);
132         memset(a, 0, sizeof a);
133         int ex = -1;
134         for (int i = 1; i <= n; ++i) {
135             scanf("%s", str + 1);
136             for (int j = 1; j <= m; ++j) {
137                 if (str[j] == '.') {
138                     a[i][j] = 1;
139                     ex = i;
140                 }
141             }
142         }
143         if (ex == -1) {
144             if (K == 0) puts("1");
145             else puts("0");
146         } else {
147             int cur = 0;
148             d[cur].init();
149             memset(d[cur].num, 0, sizeof d[cur].num);
150             d[cur].push(0, 1, 0);
151             long long ans = 0;
152             for (int i = 1; i <= n; ++i) {
153                 for (int j = 1; j <= m; ++j) {
154                     d[cur ^ 1].init();
155                     if (a[i][j]) blank(i, j, cur);
156                     else block(i, j, cur);
157                     cur ^= 1;
158                 }
159                 for(int k = 0; k < d[cur].cnt; ++k) {
160                     d[cur].st[k] <<= 2;
161                 }
162             }
163          //   for (int i = 0; i < d[cur].cnt; ++i)
164            //     printf("%d %d %d %d\n", i, d[cur].st[i], d[cur].st[i] >> mov[m + 2], d[cur].dp[i]);
165             for (int i = 0; i < d[cur].cnt; ++i) if (d[cur].num[i] == K)
166                 ans = (ans + d[cur].dp[i]) % MOD;
167             printf("%I64d\n", ans);
168         }
169     }
170     return 0;
171 }
172 
173 /*
174 
175 100
176 
177 4 4 1
178 **..
179 ....
180 ....
181 ....
182 
183 4 4 1
184 ....
185 ....
186 ....
187 ....
188     
189 4 4 2
190 ....
191 ....
192 ....
193 ....
194 
195 4 4 4
196 ....
197 ....
198 ....
199 ....
200 
201 */
View Code

TAG:控制好HASH啊。

posted @ 2015-07-13 18:41  mithrilhan  阅读(231)  评论(0编辑  收藏  举报