[URAL 1519] Formula 1 轮廓线DP 括号序列

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[URAL 1519] Formula 1 轮廓线DP 括号序列相关的知识,希望对你有一定的参考价值。

题意

  n * m 的矩形, 有坏点, 问哈密顿回路数量.

  n, m <= 11 .

 

分析

1. 确立状态

  我们考虑轮廓线DP.

  为此, 我们要刻画量化轮廓线的相关信息:

    ① 插头是否存在?

    ② 插头的连通性.

  我们发现: 插头一一对应, 且互不相交. 于是考虑使用括号序列刻画轮廓线.

  至于量化, 我们将一个括号序列当做一个三进制数即可.

2. 转移

  从上一行的最后一个, 转移到当前行的第一个: 位移.

  当前格子为坏点: 对于没有插头插到当前点的状态原样复制.

  否则:

  (1) L = # , R = #

  技术分享

  (2) L = ( , U = (

  技术分享

  (3) L = ) , U = )

  技术分享

  (4) L = ) , U = (

  技术分享

  (5) L = ), U = (

    只能出现在棋盘的最后一格.

  (6) (L != #) ^ (U != #)

     两种转移方式均可.

 

实现

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cctype>
 5 #define F(i, a, b) for (register int i = (a); i <= (b); i++)
 6 #define LL long long
 7 
 8 const int N = 15;
 9 const int B = 1600000;
10 const int Z = 50000;
11 
12 int n, m, Lx, Ly; char s[N][N];
13 
14 #define pos(x) (Dec[s] / Pow[x-1] % 3)
15 int Pow[N], Enc[B], Dec[Z], tot;
16 inline bool Legal(int s) {
17     int cnt = 0;
18     F(i, 0, m) {
19         int key = s / Pow[i] % 3;
20         if (key == 1) cnt++;
21         else if (key == 2) { if (!cnt--) return false; }
22     }
23     return !cnt;
24 }
25 void Hash(void) {
26     Pow[0] = 1; F(i, 1, m+1) Pow[i] = Pow[i-1] * 3;    
27     F(s, 0, Pow[m+1]-1)
28         if (Legal(s)) Enc[s] = ++tot, Dec[tot] = s;
29 }
30 
31 LL f[Z], g[Z];
32 
33 int main(void) {
34     #ifndef ONLINE_JUDGE
35         freopen("ural1519.in", "r", stdin);
36     #endif
37     
38     scanf("%d %d", &n, &m); F(i, 1, n) scanf("%s", s[i]+1);
39     F(i, 1, n) F(j, 1, m) if (s[i][j] == .) Lx = i, Ly = j;
40     
41     Hash();
42     
43     F(i, 1, n) {
44         if (i == 1) f[Enc[0]] = 1;
45         else {
46             memset(g, 0, sizeof g);
47             F(s, 1, tot)
48                 if (Dec[s] < Pow[m])
49                     g[Enc[Dec[s] * 3]] = f[s];
50             g[0] = 0, memcpy(f, g, sizeof g);
51         }
52         
53         F(j, 1, m) {
54             memset(g, 0, sizeof g);
55             if (s[i][j] == *) {
56                 F(s, 1, tot)
57                     g[s] = !pos(j) && !pos(j+1) ? f[s] : 0;
58             }
59             else {
60                 F(s, 1, tot) if (f[s] != 0) {
61                     int S1 = pos(j), S2 = pos(j+1);
62                     if (!S1 && !S2)
63                         g[Enc[Dec[s] + Pow[j-1] + 2 * Pow[j]]] += f[s];
64                     else if (!S1 ^ !S2) {
65                         g[s] += f[s];
66                         g[Enc[Dec[s] + (S2 - S1) * Pow[j-1] + (S1 - S2) * Pow[j]]] += f[s];
67                     }
68                     else if (S1 == 1 && S2 == 2) {
69                         if (Lx == i && Ly == j)
70                             g[Enc[Dec[s] - Pow[j-1] - 2 * Pow[j]]] += f[s];
71                     }
72                     else if (S1 == 2 && S2 == 1)
73                         g[Enc[Dec[s] - 2 * Pow[j-1] - Pow[j]]] += f[s];
74                     else if (S1 == 1 && S2 == 1) {
75                         int cnt = 1, id = j+1;
76                         for (id++; ; id++)
77                             if (pos(id) == 1) cnt++;
78                             else if (pos(id) == 2) { if (!--cnt) break; }
79                         g[Enc[Dec[s] - Pow[j-1] - Pow[j] - Pow[id-1]]] += f[s];
80                     }
81                     else {
82                         int cnt = -1, id = j;
83                         for (id--; ; id--)
84                             if (pos(id) == 2) cnt--;
85                             else if (pos(id) == 1) { if (!++cnt) break; }
86                         g[Enc[Dec[s] - 2 * Pow[j-1] - 2 * Pow[j] + Pow[id-1]]] += f[s];
87                     }
88                 }
89             }
90             g[0] = 0, memcpy(f, g, sizeof g);
91         }
92     }
93     printf("%lld\\n", f[Enc[0]]);
94     
95     return 0;
96 }

 

以上是关于[URAL 1519] Formula 1 轮廓线DP 括号序列的主要内容,如果未能解决你的问题,请参考以下文章

[URAL1519]Formula 1

URAL1519:Formula 1——题解

bzoj1814: Ural 1519 Formula 1 2011-12-20

Ural 1519 Formula 1 (DP)

BZOJ1814Ural 1519 Formula 1 插头DP

Ural1519 Formula 1