大概就是设$dp[i][x][y]$表示在第$i$个时间段,在$(x,y)$时的最大滑动距离
然后转移是$dp[i][x][y]=max(dp[i-1][x][y],dp[i][x'][y']+dis(x,y,x',y'))$
然后用单调队列进行优化,遇到障碍清除整个单调队列
1 //minamoto 2 #include<cstdio> 3 #include<cstring> 4 const int N=205; 5 template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;} 6 int n,m,sx,sy,k,ans,dp[N][N]; 7 int dx[]={0,-1,1,0,0},dy[]={0,0,0,-1,1}; 8 struct node{ 9 int dp,pos; 10 node(int dd=0,int pp=0){dp=dd,pos=pp;} 11 }q[N]; 12 char mp[N][N]; 13 void solve(int x,int y,int len,int d){ 14 int h=1,t=0; 15 for(int i=1;x>=1&&x<=n&&y>=1&&y<=m;++i,x+=dx[d],y+=dy[d]) 16 if(mp[x][y]=='x') h=1,t=0; 17 else{ 18 while(h<=t&&q[t].dp+i-q[t].pos<dp[x][y]) --t; 19 q[++t]=node(dp[x][y],i); 20 if(q[t].pos-q[h].pos>len) ++h; 21 dp[x][y]=q[h].dp+i-q[h].pos; 22 cmax(ans,dp[x][y]); 23 } 24 } 25 int main(){ 26 // freopen("testdata.in","r",stdin); 27 scanf("%d%d%d%d%d",&n,&m,&sx,&sy,&k); 28 for(int i=1;i<=n;++i) scanf("%s",mp[i]+1); 29 memset(dp,0xef,sizeof(dp)); 30 dp[sx][sy]=0; 31 while(k--){ 32 int s,t,d;scanf("%d%d%d",&s,&t,&d); 33 int len=t-s+1; 34 switch(d){ 35 case 1:for(int i=1;i<=m;++i) solve(n,i,len,d);break; 36 case 2:for(int i=1;i<=m;++i) solve(1,i,len,d);break; 37 case 3:for(int i=1;i<=n;++i) solve(i,m,len,d);break; 38 case 4:for(int i=1;i<=n;++i) solve(i,1,len,d);break; 39 } 40 } 41 printf("%d ",ans); 42 return 0; 43 }