Description
不知怎么简述题意了……看题吧……
Solution
一道不错的题目吧
定义 (f[i][x][y]) 为在 (i) 时在 ((x,y)) 上的最大经过长度
由背包的一些思想,我们可以滚掉第一维
在每个可以移动的区间的时候我们对该行或列进行更新
更新的时候的限制在障碍点和时间的限制
更新的方式是(f[x][y]=f[x][y-len]+len)
啊就是意会一下吧……
这里我们发现可以上单调队列处理这个东西
然后就对于每个区间做一下就好了
Code
#include<bits/stdc++.h>
using namespace std;
namespace yspm{
inline int read()
{
int res=0,f=1; char k;
while(!isdigit(k=getchar())) if(k=='-') f=-1;
while(isdigit(k)) res=res*10+k-'0',k=getchar();
return res*f;
}
const int N=210;
int f[N][N],n,m,k,ans;
char mp[N][N];
int fx[5]={0,-1,1,0,0};
int fy[5]={0,0,0,-1,1};
struct node{
int val,pos;
};deque<node> q;
inline bool in(int x,int y){return x<=n&&x>=1&&y>=1&&y<=m;}
inline void dp(int x,int y,int d,int tim)
{
q.clear();
for(int i=1;in(x,y);++i,x+=fx[d],y+=fy[d])
{
if(mp[x][y]=='x') {q.clear(); continue;}
while(q.size()&&q.back().val+i-q.back().pos<f[x][y]) q.pop_back();
q.push_back((node){f[x][y],i});
while(q.size()&&q.back().pos-q.front().pos>tim) q.pop_front();
f[x][y]=q.front().val+i-q.front().pos;
ans=max(ans,f[x][y]);
}return ;
}
signed main()
{
n=read(); m=read();
int p=read(),q=read(); k=read();
memset(f,-0x3f,sizeof(f)); f[p][q]=0;
for(int i=1;i<=n;++i) scanf("%s",mp[i]+1);
while(k--)
{
int s=read(),t=read(),d=read();
if(d==1) for(int i=1;i<=m;++i) dp(n,i,d,t-s+1);
if(d==2) for(int i=1;i<=m;++i) dp(1,i,d,t-s+1);
if(d==3) for(int i=1;i<=n;++i) dp(i,m,d,t-s+1);
if(d==4) for(int i=1;i<=n;++i) dp(i,1,d,t-s+1);
}printf("%d
",ans);
return 0;
}
}
signed main(){return yspm::main();}
Review
没啥 (review) 的……
在每次更新的时候记得清空 (deque) 吧……