[NOI2005]瑰丽华尔兹_动态规划_单调队列

Code:

#include<cstdio>
#include<cstring>
#include<deque>
#include<algorithm>
using namespace std;
const int N = 200 + 3;
char map[N][N];
int n, m, k, dp[N][N], fin;
struct Node{ 
    int x, y, val;
    Node(int x = 0, int y = 0,int val = 0): x(x), y(y), val(val){}
};
deque<Node>Q;
inline void erase_q(){ while(!Q.empty()) Q.pop_front();}
inline int dist(int a,int b, int c,int d){ return abs(a - c) + abs(b- d);}
inline void solve(int y,int x,int d,int len,int h)
{
    erase_q();
    Q.push_back(Node(x, y, dp[x][y]));
    for(int i = 1;i < h; ++i)
    {
        if(d == 1) --y;  if(d == 2) ++y;
        if(d == 3) --x;  if(d == 4) ++x;
        if(map[y][x] == 'x'){ erase_q(); continue; }
        while(!Q.empty() && dist(Q.front().x, Q.front().y , x , y) > len) Q.pop_front();
        while(!Q.empty() && dist(Q.back(). x, Q.back(). y, x , y) + Q.back().val <= dp[x][y]) Q.pop_back();
        Q.push_back(Node(x , y, dp[x][y]));
        dp[x][y] = dist(Q.front(). x , Q.front().y, x , y) + Q.front().val;
        fin = max(fin, dp[x][y]);
    }
}
int main()
{
    memset(dp, -0x3f, sizeof(dp));
    int x, y;
    scanf("%d%d%d%d%d",&n,&m,&x,&y,&k);
    dp[y][x] = 0;
    for(int i = 1;i <= n; ++i) scanf("%s",map[i] + 1);
    for(int i = 1;i <= k; ++i)
    {
        int s, t, d;
        scanf("%d%d%d",&s,&t,&d);
        if(d == 1) for(int i = 1;i <= m; ++i) solve(n, i, d, t - s + 1, n);
        if(d == 2) for(int i = 1;i <= m; ++i) solve(1, i, d, t - s + 1, n);
        if(d == 3) for(int i = 1;i <= n; ++i) solve(i, m, d, t - s + 1, m);
        if(d == 4) for(int i = 1;i <= n; ++i) solve(i, 1, d, t - s + 1, m);
    }
    printf("%d",fin);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/liyong1009s/article/details/82792000
今日推荐