单调队列实现好题。
设\(f[k][i][j]\)表示第\(k\)段区间在\((i,j)\)出的最优答案。
\(f[k][i][j]=max(f[k-1][I][J]+Dis)\)(\(Dis\)是距离,\((I,J)\)是上一个合法位置。懒得写了。。。)
考虑单调队列加滚动数组解决\(MLE,TLE\)的问题。。。
在遇到障碍物时清零队列即可。。。
注意在将\(f[i][j]\)加入队列之前,不能更新答案,因为我们的\(max\)是\(k-1\)的\(max\),更新之后回锅。。。
#include<bits/stdc++.h> using namespace std; inline int read() { int f=1,w=0;char x=0; while(x<'0'||x>'9') {if(x=='-') f=-1; x=getchar();} while(x!=EOF&&x>='0'&&x<='9') {w=(w<<3)+(w<<1)+(x^48);x=getchar();} return w*f; } const int N=250; struct Group{int Val,Stp;} Q[N]; int n,m,Sx,Sy,K,ans,Mp[N][N],f[N][N]; int dx[5]={0,-1,1,0,0},dy[5]={0,0,0,-1,1}; inline void Dp(int X,int Y,int S,int D) { int H=1,T=0; for(int Stp=1;1<=X&&X<=n&&1<=Y&&Y<=m;Stp++,X+=dx[D],Y+=dy[D]) if(!Mp[X][Y]) H=1,T=0; else { while(H<=T&&Q[T].Val+Stp-Q[T].Stp<f[X][Y]) T--; Q[++T]=(Group){f[X][Y],Stp}; while(H<=T&&Q[T].Stp-Q[H].Stp>S) H++; f[X][Y]=Q[H].Val+Stp-Q[H].Stp;ans=max(ans,f[X][Y]); } } int main(){ #ifndef ONLINE_JUDGE freopen("A.in","r",stdin); #endif n=read(),m=read(),Sx=read(),Sy=read(),K=read(); for(int i=1;i<=n;i++) { string S;cin>>S; for(int j=0;j<m;j++) if(S[j]=='.') Mp[i][j+1]=1; else Mp[i][j+1]=0; } memset(f,0xf3,sizeof(f));f[Sx][Sy]=0; for(int i=1;i<=K;i++) { int L=read(),R=read(),D=read(); if(D==1) for(int j=1;j<=m;j++) Dp(n,j,R-L+1,D); if(D==2) for(int j=1;j<=m;j++) Dp(1,j,R-L+1,D); if(D==3) for(int j=1;j<=n;j++) Dp(j,m,R-L+1,D); if(D==4) for(int j=1;j<=n;j++) Dp(j,1,R-L+1,D); } printf("%d\n",ans); }