DP方程不难想 主要是优化
首先可以暴力AC 成就感满满
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x){
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
inline void read(char *s){
char c=nc(); int len=0;
for (;!(c=='.' || c=='x');c=nc());
for (;c=='.' || c=='x';s[++len]=c,c=nc()); s[++len]=0;
}
#define Max(a,b) ((a)<(b)?(a)=(b):0)
const int N=205;
const int dx[]={0,-N,N,-1,1};
int n,m,K,T;
char Map[N*N];
int d[40005];
int f[N*N];
int *pt[5][N*N];
int tot[5];
#define P(i,j) (((i)-1)*m+(j))
int main(){
int ix,iy,il,ir,id;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(n); read(m); read(ix); read(iy); read(K);
for (int i=1;i<=n;i++) read(Map+(i-1)*m);
for (int i=1;i<=K;i++){
read(il); read(ir); read(id);
for (int j=il;j<=ir;j++) d[j]=id; T=ir;
}
for (int i=1;i<n;i++) for (int j=1;j<=m;j++) if (Map[P(i,j)]!='x') pt[1][++tot[1]]=f+P(i,j); pt[1][++tot[1]]=NULL;
for (int i=n;i>1;i--) for (int j=1;j<=m;j++) if (Map[P(i,j)]!='x') pt[2][++tot[2]]=f+P(i,j); pt[2][++tot[2]]=NULL;
for (int i=1;i<=n;i++) for (int j=1;j<m;j++) if (Map[P(i,j)]!='x') pt[3][++tot[3]]=f+P(i,j); pt[3][++tot[3]]=NULL;
for (int i=1;i<=n;i++) for (int j=m;j>1;j--) if (Map[P(i,j)]!='x') pt[4][++tot[4]]=f+P(i,j); pt[4][++tot[4]]=NULL;
for (int i=1;i<=n*m;i++) f[i]=-1<<30;
f[P(ix,iy)]=0;
for (int t=1;t<=T;t++)
if (d[t]==1){
for (int **i=pt[1]+1;*i;i++)
Max(**i,*(*i+m)+1);
}else if (d[t]==2){
for (int **i=pt[2]+1;*i;i++)
Max(**i,*(*i-m)+1);
}else if (d[t]==3){
for (int **i=pt[3]+1;*i;i++)
Max(**i,*(*i+1)+1);
}else if (d[t]==4){
for (int **i=pt[4]+1;*i;i++)
Max(**i,*(*i-1)+1);
}
int Ans=0;
for (int i=1;i<=n*m;i++) Max(Ans,f[i]);
printf("%d\n",Ans);
return 0;
}
正解是方向相同的时间段可以一起处理 可以直接RMQ做 knmlogn
当然最好单调队列 knm
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x){
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc());
}
inline void read(char *s){
char c=nc(); int len=0;
for (;!(c=='.' || c=='x');c=nc());
for (;c=='.' || c=='x';s[++len]=c,c=nc()); s[++len]=0;
}
const int N=205;
int n,m,K;
int len[N],d[N];
char Map[N][N];
int f[2][N][N];
int l,r,Q[N];
int main(){
int ix,iy,il,ir;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(n); read(m); read(ix); read(iy); read(K);
for (int i=1;i<=n;i++) read(Map[i]);
for (int i=1;i<=K;i++)
read(il),read(ir),read(d[i]),len[i]=ir-il+1;
int t=0;
for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) f[0][i][j]=-1<<30;
f[0][ix][iy]=0;
for (int k=1;k<=K;k++,t^=1)
if (d[k]==2){
for (int j=1;j<=m;j++){
l=r=-1;
for (int i=1;i<=n;i++)
if (Map[i][j]=='x'){
while (l<r) l++;
}else{
while (l<r && i-Q[l+1]>len[k]) l++;
f[t^1][i][j]=f[t][i][j];
if (l<r)
f[t^1][i][j]=max(f[t^1][i][j],f[t][Q[l+1]][j]-Q[l+1]+i);
while (l<r && f[t][i][j]-i>=f[t][Q[r]][j]-Q[r]) r--;
Q[++r]=i;
}
}
}else if (d[k]==1){
for (int j=1;j<=m;j++){
l=r=-1;
for (int i=n;i;i--)
if (Map[i][j]=='x'){
while (l<r) l++;
}else{
while (l<r && Q[l+1]-i>len[k]) l++;
f[t^1][i][j]=f[t][i][j];
if (l<r)
f[t^1][i][j]=max(f[t^1][i][j],f[t][Q[l+1]][j]+Q[l+1]-i);
while (l<r && f[t][i][j]+i>=f[t][Q[r]][j]+Q[r]) r--;
Q[++r]=i;
}
}
}else if (d[k]==4){
for (int i=1;i<=n;i++){
l=r=-1;
for (int j=1;j<=m;j++)
if (Map[i][j]=='x'){
while (l<r) l++;
}else{
while (l<r && j-Q[l+1]>len[k]) l++;
f[t^1][i][j]=f[t][i][j];
if (l<r)
f[t^1][i][j]=max(f[t^1][i][j],f[t][i][Q[l+1]]-Q[l+1]+j);
while (l<r && f[t][i][j]-j>=f[t][i][Q[r]]-Q[r]) r--;
Q[++r]=j;
}
}
}else if (d[k]==3){
for (int i=1;i<=n;i++){
l=r=-1;
for (int j=m;j;j--)
if (Map[i][j]=='x'){
while (l<r) l++;
}else{
while (l<r && Q[l+1]-j>len[k]) l++;
f[t^1][i][j]=f[t][i][j];
if (l<r)
f[t^1][i][j]=max(f[t^1][i][j],f[t][i][Q[l+1]]+Q[l+1]-j);
while (l<r && f[t][i][j]+j>=f[t][i][Q[r]]+Q[r]) r--;
Q[++r]=j;
}
}
}
int Ans=0;
for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) Ans=max(Ans,f[t][i][j]);
printf("%d\n",Ans);
return 0;
}