裸DP (知道要用单调队列的前提下)按照时间区间做DP 单调队列也没什么特别的 就是手写双端队列要注意清0 以及各种数组加减号有点容易打错略坑
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define MAXN 200
char Map[MAXN+10][MAXN+10];
int dp[MAXN+10][MAXN+10][MAXN+10];
int n, m, K;
struct node{
int st, ed, dir;
}A[MAXN+10];
int Q[MAXN*10+10];
int F, R;
int main()
{
int stx, sty;
scanf("%d%d%d%d%d", &n, &m, &stx, &sty, &K);
for(int i = 1; i <= n; i++) scanf("%s", Map[i]+1);
memset(dp, ~0x3f, sizeof(dp));
dp[0][stx][sty] = 0;
for(int i = 1; i <= K; i++) scanf("%d%d%d", &A[i].st, &A[i].ed, &A[i].dir);
for(int d = 1; d <= K; d++)
{
int T = A[d].ed - A[d].st + 1, dir = A[d].dir;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
dp[d][i][j] = dp[d-1][i][j];
if(dir == 1)
for(int j = 1; j <= m; j++)
{
F = R = Q[0] = 0;
memset(Q, 0, sizeof(Q));
for(int i = n; i >= 1; i--)
{
if(Map[i][j] == 'x') { F = R = Q[0] = 0; continue; }
while(F < R && Q[F] - i > T) F++;
dp[d][i][j] = max(dp[d][i][j], dp[d-1][Q[F]][j] + Q[F] - i);
while(F < R && dp[d-1][i][j] + i >= dp[d-1][Q[R-1]][j] + Q[R-1]) R--;
Q[R++] = i;
}
}
if(dir == 2)
for(int j = 1; j <= m; j++)
{
F = R = Q[0] = 0;
memset(Q, 0, sizeof(Q));
for(int i = 1; i <= n; i++)
{
if(Map[i][j] == 'x') { F = R = Q[0] = 0; continue; }
while(F < R && i - Q[F] > T) F++;
dp[d][i][j] = max(dp[d][i][j], dp[d-1][Q[F]][j] + i - Q[F]);
while(F < R && dp[d-1][i][j] - i >= dp[d-1][Q[R-1]][j] - Q[R-1]) R--;
Q[R++] = i;
}
}
if(dir == 3)
for(int i = 1; i <= n; i++)
{
F = R = Q[0] = 0;
memset(Q, 0, sizeof(Q));
for(int j = m; j >= 1; j--)
{
if(Map[i][j] == 'x') { F = R = Q[0] = 0; continue; }
while(F < R && Q[F] - j > T) F++;
dp[d][i][j] = max(dp[d][i][j], dp[d-1][i][Q[F]] + Q[F] - j);
while(F < R && dp[d-1][i][j] + j >= dp[d-1][i][Q[R-1]] + Q[R-1]) R--;
Q[R++] = j;
}
}
if(dir == 4)
for(int i = 1; i <= n; i++)
{
F = R = Q[0] = 0;
for(int j = 1; j <= m; j++)
{
if(Map[i][j] == 'x') { F = R = Q[0] = 0; continue; }
while(F < R && j - Q[F] > T) F++;
dp[d][i][j] = max(dp[d][i][j], dp[d-1][i][Q[F]] - Q[F] + j);
while(F < R && dp[d-1][i][j] - j >= dp[d-1][i][Q[R-1]] - Q[R-1]) R--;
Q[R++] = j;
}
}
}
int Ans = -1;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
Ans = max(Ans, dp[K][i][j]);
printf("%d", Ans);
}