单调队列很好想。。。但是实现需要优化一下代码复杂度。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 205 #define inf 2000000000 using namespace std; int n,m,x,y,k,map[maxn][maxn],q[maxn],pos[maxn],dp[maxn][maxn][maxn],ans=0; int s,t,d,head,tail,now; int dx[]={0,-1,1,0,0},dy[]={0,0,0,-1,1}; char ss[maxn]; bool check(int x,int y) { if ((x>=1) && (x<=n) && (y>=1) && (y<=m)) return true; return false; } void dps(int k,int x,int y,int d) { head=1;tail=0;now=1; while (check(x,y)) { if (map[x][y]) {dp[k][x][y]=-inf;head=1;tail=0;} else { while ((head<=tail) && (now-pos[head]>t-s+1)) head++; while ((head<=tail) && (dp[k-1][x][y]-now>=q[tail])) tail--; q[++tail]=dp[k-1][x][y]-now;pos[tail]=now; dp[k][x][y]=q[head]+now;ans=max(ans,dp[k][x][y]); } x+=dx[d];y+=dy[d];now++; } } int main() { scanf("%d%d%d%d%d",&n,&m,&x,&y,&k); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) dp[0][i][j]=-inf; dp[0][x][y]=0; for (int i=1;i<=n;i++) { scanf("%s",ss+1); for (int j=1;j<=m;j++) if (ss[j]=='x') map[i][j]=1; } for (int i=1;i<=k;i++) { scanf("%d%d%d",&s,&t,&d); if (d==1) for (int j=1;j<=m;j++) dps(i,n,j,1); else if (d==2) for (int j=1;j<=m;j++) dps(i,1,j,2); else if (d==3) for (int j=1;j<=n;j++) dps(i,j,m,3); else for (int j=1;j<=n;j++) dps(i,j,1,4); } printf("%d\n",ans); return 0; }