"NOI 2005" magnificent waltz

Title effect: Given a $ n times m $ board, starting at $ (x, y) $, $ k $ given time periods, each time period a given direction of movement, each time can be specified to the current the direction of movement of a step or stay still, not hitting obstacles or out of the board, can go up to ask how many steps. $ N, m, k leq 200 $

Provided $ f [k] [i] [j] $ denotes the end of the walk time period $ k $ $ (i, j) $ maximum sliding distance, expressed as unreachable $ -infty $, $ len provided = t_k-s_k + 1 $, i.e. $ k $ duration of the time periods.

To go to the right, for example, there is the state transition equation

Monotonous queue maintains a monotonically increasing $ t $, $ f $ monotonically decreasing.

#include <cstdio>

const int N = 205, INF = 0x7fffffff;
const int dx[5] = {0, -1, 1, 0, 0};
const int dy[5] = {0, 0, 0, -1, 1};

char a[N][N]; int n, m, f[N][N], q[N][2], ans;

int read() {
    int x = 0; char c = getchar();
    while (c < '0' || c > '9') c = getchar();
    while (c >= '0' && c <= '9') {
        x = (x << 3) + (x << 1) + (c ^ 48);
        c = getchar();
    }
    return x;
}
int max(int x, int y) {
    return x > y ? x : y;
}
void solve(int x, int y, int len, int d) {
    int head = 1, tail = 0;
    for (int i = 1; x >= 1 && x <= n && y >= 1 && y <= m; x += dx[d], y += dy[d], ++i) {
        if (a[x][y] == 'x') head = 1, tail = 0;
        else {
            while (head <= tail && q[tail][1] + i - q[tail][0] < f[x][y]) --tail;
            q[++tail][0] = i, q[tail][1] = f[x][y];
            if (q[tail][0] - q[head][0] > len) ++head;
            f[x][y] = q[head][1] + i - q[head][0];
            ans = max(ans, f[x][y]);
        }
    }
}

int main() {
    n = read(), m = read(); int x = read(), y = read(), k = read();
    for (int i = 1; i <= n; ++i) scanf("%s", a[i] + 1);
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j) f[i][j] = -INF;
    f[x][y] = 0;
    while (k--) {
        int s = read(), t = read(), d = read();
        if (d == 1) for (int i = 1; i <= m; ++i) solve(n, i, t - s + 1, d); //up
        if (d == 2) for (int i = 1; i <= m; ++i) solve(1, i, t - s + 1, d); //down
        if (d == 3) for (int i = 1; i <= n; ++i) solve(i, m, t - s + 1, d); //left
        if (d == 4) for (int i = 1; i <= n; ++i) solve(i, 1, t - s + 1, d); //right
    }
    printf("%dn", ans);
    return 0;
}

Time complexity $ O (nmk) $

Original: Big Box  "NOI 2005" magnificent waltz


Guess you like

Origin www.cnblogs.com/petewell/p/11611534.html