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

本文介绍了一种使用C++实现的迷宫寻路算法,通过定义节点结构体和双端队列,实现了对迷宫地图的遍历和最短路径的计算。算法采用动态规划思想,结合距离计算和队列操作,有效解决了迷宫寻路问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

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;
}

  

转载于:https://www.cnblogs.com/guangheli/p/9845156.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值