Channel: http://acm.timus.ru/problem.aspx?space=1&num=1519
Test instructions: Single loop, through all the points, there is a blocking point.
Code:
#include <cstdio> #include <cstring> #include <algorithm>using namespace std;const int max_n = 13;const int max_m = 13;const int HASH = 10007;const int max_s = 1000007; struct Node {int Head[hash], Nxt[max_s];long long dp[max_s], st[max_s];int cnt; void Init () {memset (head,-1, sizeof head); CNT = 0; } void push (long long s, Long long v) {int now = s% HASH; for (int i = head[now]; ~i; i = Nxt[i]) if (st[i] = = s) {Dp[i] + = V; return; }ST[CNT] = s; DP[CNT] = v; NXT[CNT] = Head[now]; Head[now] = cnt++; }}d[2];int N, m;int ex, Ey;int Find_pos (long long S, int p) {return (S >> (P << 1)) & 3;} void TP (Long long &s, int p, long long v) {s &= (~ (3ll << (P << 1))); S |= (v << (P << 1));} int Find_r (long long S, int p) {int cnt = 0; for (int i = p; I <= m; ++i) {if (Find_pos (s, i) = = 1) ++cnt; else if (Find_pos (s, i) = = 2)--cnt; if (!cnt) return i; }}int find_l (long long S, int p) {int cnt = 0; for (int i = p; I >= 0; i.) {if (Find_pos (s, i) = = 2) ++cnt; else if (Find_pos (s, i) = = 1)--cnt; if (!cnt) return i; }}void Blank (int i, int j, int cur) {for (int k = 0; k < d[cur].cnt; ++k) {long Long T = d[cur].st[k]; int L = find_pos (T, j-1), r = Find_pos (t, j); if (l && r) {if (L = = 1 && r = = 1) {int tpos = Find_r (t, j); TP (T, j-1, 0); TP (T, j, 0); TP (T, TPOs, 1); d[cur ^ 1].push (t, D[cur].dp[k]); } else if (L = = 2 && r = = 1) {TP (T, j-1, 0); TP (T, j, 0); d[cur ^ 1].push (t, D[cur].dp[k]); } else if (L = = 2 && r = = 2) {int tpos = find_l (t, j-1); TP (T, j-1, 0); TP (T, j, 0); TP (T, TPOs, 2); d[cur ^ 1].push (t, D[cur].dp[k]); } else {//last non-barrierLattice TP (T, j-1, 0); TP (T, j, 0); if (!t) if (i = = Ex && j = = ey) d[cur ^ 1].push (t, D[cur].dp[k]); }} else if (l) {if (I < n) {d[cur ^ 1].push (t, D[cur].dp[k]); } if (J < m) {TP (T, j-1, 0); TP (T, J, L); d[cur ^ 1].push (t, D[cur].dp[k]); }} else if (r) {if (J < m) {d[cur ^ 1].push (t, D[cur].dp[k]); } if (I < n) {TP (T, j-1, R); TP (T, j, 0); d[cur ^ 1].push (t, D[cur].dp[k]); }} else {//new if (I < n && J < m) {TP (T, j-1, 1); TP (T, J, 2); d[cur ^ 1].push (t, D[cur].dp[k]); }}}} void block (int i, int j, int cur) {for (int k = 0; k < d[cur].cnt; ++k) {long Long T = d[cur].st[k];in T L = find_pos (T, j-1), r = Find_pos (t, j); if (!l &&!r) d[cur ^ 1].push (t, D[cur].dp[k]);}} Char str[17];int a[max_n][max_m];int Main () {while (2 = = scanf ("%d%d", &n, &m)) {memset (A, 0, sizeof a); ex = EY =-1; for (int i = 1; I <= n; ++i) {scanf ("%s", str + 1); for (int j = 1; j <= m; ++j) {if (str[j] = = '. ') {A[i][j] = 1; ex = i, ey = j; }}} if (ex = =-1) puts ("0"); else {int cur = 0; D[cur].init (); D[cur].push (0, 1); A long long ans = 0; for (int i = 1, i <= N; ++i) {for (int j = 1; j <= m; ++j) {d[cur ^ 1].init (); if (A[i][j]) blank (i, j, cur); else Block (i, J, cur); Cur ^= 1; } for (int k = 0; k < d[cur].cnt; ++k) {d[cur].st[k] <<= 2; }} for (int i = 0; i < d[cur].cnt; ++i) ans + = d[cur].dp[i]; printf ("%i64d\n", ans); }} return 0;}
"Plug DP" URAL 1519 Formula 1