# 1499: [NOI2005]瑰丽华尔兹

Time Limit: 3 Sec Memory Limit: 64 MB
Submit: 1321 Solved: 788
[Submit][Status][Discuss]
Description

Input

Output

Sample Input

4 5 4 1 3

..xx.

.....

...x.

.....

1 3 4

4 5 1

6 7 3


Sample Output

6


f[i][j]$f[i][j]$表示在i,j$i,j$这个格子的最优值，那么对于每一次的改变方向的转移都是n3$n^3$的。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=210;
int n,m,X,Y,K,mp[N][N],f[N][N],q[N],g[N][N],inf;
inline void work(int len,int kind){
int i,j,h,t;
if(kind==1){
for(j=1;j<=m;++j)
for(h=1,t=0,i=n;i;--i){
if(!mp[i][j]){
h=1,t=0;g[i][j]=inf;
continue;
}
while(h<=t&&f[i][j]>=f[q[t]][j]+q[t]-i) --t;
q[++t]=i;
while(h<t&&q[h]-i>len) ++h;
g[i][j]=(f[q[h]][j]==inf)?inf:(f[q[h]][j]+q[h]-i);
}
return ;
}
if(kind==2){
for(j=1;j<=m;++j)
for(h=1,t=0,i=1;i<=n;++i){
if(!mp[i][j]){
h=1,t=0;g[i][j]=inf;
continue;
}
while(h<=t&&f[i][j]>=f[q[t]][j]+i-q[t]) --t;
q[++t]=i;
while(h<t&&i-q[h]>len) ++h;
g[i][j]=(f[q[h]][j]==inf)?inf:(f[q[h]][j]+i-q[h]);
}
return ;
}
if(kind==3){
for(i=1;i<=n;++i)
for(h=1,t=0,j=m;j;--j){
if(!mp[i][j]){
h=1,t=0;g[i][j]=inf;
continue;
}
while(h<=t&&f[i][j]>=f[i][q[t]]+q[t]-j) --t;
q[++t]=j;
while(h<t&&q[h]-j>len) ++h;
g[i][j]=(f[i][q[h]]==inf)?inf:(f[i][q[h]]+q[h]-j);
}
return ;
}
if(kind==4){
for(i=1;i<=n;++i)
for(h=1,t=0,j=1;j<=m;++j){
if(!mp[i][j]){
h=1,t=0;g[i][j]=inf;
continue;
}
while(h<=t&&f[i][j]>=f[i][q[t]]+j-q[t]) --t;
q[++t]=j;
while(h<t&&j-q[h]>len) ++h;
g[i][j]=(f[i][q[h]]==inf)?inf:(f[i][q[h]]+j-q[h]);
}
return ;
}
}
int main(){
int i,j,x,y,z;
scanf("%d%d%d%d%d",&n,&m,&X,&Y,&K);
for(i=1;i<=n;++i)
for(j=1;j<=m;++j){
char ch=getchar();
while(ch!='.'&&ch!='x') ch=getchar();
mp[i][j]=(ch=='.');
}
memset(f,-10,sizeof(f));
f[X][Y]=0;inf=f[0][0];
while(K--){
scanf("%d%d%d",&x,&y,&z);
work(y-x+1,z);
for(i=1;i<=n;++i)
for(j=1;j<=m;++j)
f[i][j]=max(f[i][j],g[i][j]);
}
int ans=0;
for(i=1;i<=n;++i)
for(j=1;j<=m;++j)
ans=max(ans,f[i][j]);
printf("%d\n",ans);
}