ural 1519 Formula 1(插头dp)
1519. Formula 1 @ Timus Online Judge
干了一天啊!!!插头DP入门。
代码如下:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 #include <ctime> 6 #include <cmath> 7 8 using namespace std; 9 typedef long long LL; 10 11 const int N = 15; 12 const int M = 1666666; 13 LL pw[N], dp[2][M]; 14 int stk[2][M], top[2]; 15 char mat[N][N]; 16 bool vis[M]; 17 18 void PRE() { 19 pw[0] = 1; 20 for (int i = 1; i < N; i++) pw[i] = pw[i - 1] * 3; 21 } 22 23 inline int getst(int st, int k) { return st / pw[k] % 3;} 24 inline void print(int st, int n) { for (int i = n; i >= 0; i--) printf("%d", getst(st, i));} 25 26 LL work(int n, int m) { 27 bool fi = true; 28 int cur = 0, ei, ej, nx, st, hi, lo; 29 memset(dp, 0, sizeof(dp)); 30 memset(vis, 0, sizeof(vis)); 31 memset(top, 0, sizeof(top)); 32 for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) if (mat[i][j] == '.') ei = i, ej = j; 33 for (int i = 0; i < n; i++) { 34 for (int j = 0; j < m; j++) { 35 /************* debug ****************/ 36 //cout << i << ' ' << j << ' ' << top[cur] << endl; 37 //for (int k = 0; k < top[cur]; k++) { 38 //st = stk[cur][k]; 39 //print(st, m); cout << "~" << dp[cur][st] << ' '; 40 //} 41 //cout << endl; 42 /************************************/ 43 if (i == ei && j == ej) return dp[cur][pw[m] << 1 | 1]; 44 for (int k = 0; k < top[cur]; k++) vis[stk[cur][k]] = false; 45 cur ^= 1; 46 for (int k = 0; k < top[cur]; k++) dp[cur][stk[cur][k]] = 0; 47 top[cur] = 0; 48 if (mat[i][j] == '*') { 49 if (fi) continue; 50 for (int k = 0; k < top[cur ^ 1]; k++) { 51 st = stk[cur ^ 1][k]; 52 if (getst(st, m)) continue; 53 nx = st * 3; 54 dp[cur][nx] += dp[cur ^ 1][st]; 55 if (!vis[nx]) vis[stk[cur][top[cur]++] = nx] = true; 56 } 57 } else { 58 if (fi) { 59 dp[cur][5] = 1; 60 vis[stk[cur][top[cur]++] = 5] = true; 61 fi = false; 62 } else { 63 for (int k = 0; k < top[cur ^ 1]; k++) { 64 st = stk[cur ^ 1][k]; 65 lo = getst(st, 0), hi = getst(st, m); 66 if (lo == 0) { 67 if (hi == 0) { 68 nx = st * 3 + 5; 69 dp[cur][nx] += dp[cur ^ 1][st]; 70 if (!vis[nx]) vis[stk[cur][top[cur]++] = nx] = true; 71 } else if (hi == 1) { 72 if (i == 0 || mat[i - 1][j] == '*') continue; 73 nx = (st * 3 + 1) % pw[m + 1]; 74 dp[cur][nx] += dp[cur ^ 1][st]; 75 if (!vis[nx]) vis[stk[cur][top[cur]++] = nx] = true; 76 nx = (st * 3 + 3) % pw[m + 1]; 77 dp[cur][nx] += dp[cur ^ 1][st]; 78 if (!vis[nx]) vis[stk[cur][top[cur]++] = nx] = true; 79 } else { 80 if (i == 0 || mat[i - 1][j] == '*') continue; 81 nx = (st * 3 + 2) % pw[m + 1]; 82 dp[cur][nx] += dp[cur ^ 1][st]; 83 if (!vis[nx]) vis[stk[cur][top[cur]++] = nx] = true; 84 nx = (st * 3 + 6) % pw[m + 1]; 85 dp[cur][nx] += dp[cur ^ 1][st]; 86 if (!vis[nx]) vis[stk[cur][top[cur]++] = nx] = true; 87 } 88 } else if (lo == 1) { 89 if (j == 0 || mat[i][j - 1] == '*') continue; 90 if (hi == 0) { 91 nx = st * 3 % pw[m + 1]; 92 dp[cur][nx] += dp[cur ^ 1][st]; 93 if (!vis[nx]) vis[stk[cur][top[cur]++] = nx] = true; 94 nx = (st * 3 - 2) % pw[m + 1]; 95 dp[cur][nx] += dp[cur ^ 1][st]; 96 if (!vis[nx]) vis[stk[cur][top[cur]++] = nx] = true; 97 } else if (hi == 1) { 98 if (i == 0 || mat[i - 1][j] == '*') continue; 99 int cnt = 0, i = m - 1, t; 100 for ( ; i >= 0; i--) { 101 t = getst(st, i); 102 if (t == 1) cnt++; 103 if (t == 2) { 104 if (cnt) cnt--; 105 else break; 106 } 107 } 108 nx = (st - pw[i] - 1) * 3 % pw[m + 1]; 109 //print(st, m); putchar(' '); print(nx, m); puts(""); 110 dp[cur][nx] += dp[cur ^ 1][st]; 111 if (!vis[nx]) vis[stk[cur][top[cur]++] = nx] = true; 112 } else {} 113 } else { 114 if (j == 0 || mat[i][j - 1] == '*') continue; 115 if (hi == 0) { 116 nx = st * 3 % pw[m + 1]; 117 dp[cur][nx] += dp[cur ^ 1][st]; 118 if (!vis[nx]) vis[stk[cur][top[cur]++] = nx] = true; 119 nx = (st * 3 - 4) % pw[m + 1]; 120 dp[cur][nx] += dp[cur ^ 1][st]; 121 if (!vis[nx]) vis[stk[cur][top[cur]++] = nx] = true; 122 } else if (hi == 1) { 123 if (i == 0 || mat[i - 1][j] == '*') continue; 124 nx = st / 3 * 9 % pw[m + 1]; 125 dp[cur][nx] += dp[cur ^ 1][st]; 126 if (!vis[nx]) vis[stk[cur][top[cur]++] = nx] = true; 127 } else { 128 if (i == 0 || mat[i - 1][j] == '*') continue; 129 int cnt = 0, i = 1, t; 130 for ( ; i <= m; i++) { 131 t = getst(st, i); 132 if (t == 2) cnt++; 133 if (t == 1) { 134 if (cnt) cnt--; 135 else break; 136 } 137 } 138 nx = (st + pw[i] - 2) * 3 % pw[m + 1]; 139 dp[cur][nx] += dp[cur ^ 1][st]; 140 if (!vis[nx]) vis[stk[cur][top[cur]++] = nx] = true; 141 } 142 } 143 } 144 } 145 } 146 } 147 } 148 return 0; 149 } 150 151 int main() { 152 //freopen("in", "r", stdin); 153 //freopen("out", "w", stdout); 154 //time_t t1 = clock(); 155 int n, m; 156 PRE(); 157 //cout << (double) (clock() - t1) / CLOCKS_PER_SEC << endl; 158 while (cin >> n >> m) { 159 for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) cin >> mat[i][j]; mat[i][m] = 0;} 160 cout << work(n, m) << endl; 161 //cout << (double) (clock() - t1) / CLOCKS_PER_SEC << endl; 162 } 163 return 0; 164 }
——written by Lyon