POJ 1739 Tony's Tour——插头dp

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 15;
const int seed = 2e5 + 7;
typedef long long ll;
char ch;
int n, m, a[maxn][maxn], bit[maxn*2];
int pre, cur, total[2], state[2][seed];
ll dp[2][seed], ans;
int tot, head[seed];
struct Edge { int to, next; } edges[seed];
void init() {
    memset(a, 0, sizeof(a));
    for (int i = 0; i < maxn*2; i++) bit[i] = i<<1;
    pre = -1, cur = 0;
    total[0] = 1;
    state[0][1] = 0;
    dp[0][1] = 1;
    ans = 0;
}
void addedge(int s, ll num) {
    int u = s % seed;
    for (int i = head[u]; ~i; i = edges[i].next) {
        int v = edges[i].to;
        if (state[cur][v] == s) {
            dp[cur][v] += num;
            return;
        }
    }
    total[cur]++;
    edges[++tot].to = total[cur];
    edges[tot].next = head[u];
    head[u] = tot;
    state[cur][total[cur]] = s;
    dp[cur][total[cur]] = num;
}
void plugdp() {
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            tot = 0;
            memset(head, -1, sizeof(head));
            pre = cur; cur ^= 1;
            total[cur] = 0;
            for (int k = 1; k <= total[pre]; k++) {
                int s = state[pre][k];
                ll num = dp[pre][k];
                int r = (s>>bit[j-1])%4;
                int d = (s>>bit[j])%4;
                if (!a[i][j]) {
                    if (!r && !d) addedge(s, num);
                }
                else if (!r && !d) {
                    if (a[i][j+1] && a[i+1][j]) addedge(s+(1<<bit[j-1])+2*(1<<bit[j]), num);
                }
                else if (!r && d) {
                    if (a[i][j+1]) addedge(s, num);
                    if (a[i+1][j]) addedge(s+d*(1<<bit[j-1])-d*(1<<bit[j]), num);
                }
                else if (r && !d) {
                    if (a[i+1][j]) addedge(s, num);
                    if (a[i][j+1]) addedge(s+r*(1<<bit[j])-r*(1<<bit[j-1]), num);
                }
                else if (r == 1 && d == 1) {
                    int temp = 1;
                    for (int u = j+1; u <= m; u++) {
                        int v = (s>>bit[u])%4;
                        if (v == 1) temp++;
                        else if (v == 2) temp--;
                        if (!temp) {
                            addedge(s-(1<<bit[u])-(1<<bit[j-1])-(1<<bit[j]), num); break;
                        }
                    }
                }
                else if (r == 2 && d == 2) {
                    int temp = 1;
                    for (int u = j-2; u >= 0; u--) {
                        int v = (s>>bit[u])%4;
                        if (v == 2) temp++;
                        else if (v == 1) temp--;
                        if (!temp) {
                            addedge(s+(1<<bit[u])-2*(1<<bit[j-1])-2*(1<<bit[j]), num); break;
                        }
                    }
                }
                else if (r == 2 && d == 1) {
                    addedge(s-2*(1<<bit[j-1])-(1<<bit[j]), num);
                }
                else if (r == 1 && d == 2) {
                    if (i == n && j == m) ans += num;
                }
            }
        }
        for (int j = 1; j <= total[cur]; j++) state[cur][j] <<= 2;
    }
}
int main() {
    while (~scanf("%d%d", &n, &m) && n+m) {
        init();
        for (int i = 1; i <= n; i++) {
            getchar();
            for (int j = 1; j <= m; j++) {
                scanf("%c", &ch);
                if (ch == '.') a[i][j] = 1;
            }
        }
        n += 2;
        a[n-1][1] = a[n-1][m] = 1;
        for (int i = 1; i <= m; i++) a[n][i] = 1;
        plugdp();
        printf("%lld\n", ans);
    }
    return 0;
}

 

发布了733 篇原创文章 · 获赞 498 · 访问量 18万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览