問題への解決策 - [NOI2005]壮大なワルツ
\(N \回\ m)の行列。((x、y)を\ \ ) 出発点として。合計\(K \)の期間、各時間\([S_I、T_I(+ T_I。1. 1 + = S_ {I})\) 、第二缶(D_I \)\ユニットの移動の方向(ありませんマトリックスを越えて、我々は、与えられた行列で障害物に来ることができない、\ ({1,2,3,4 \} \ D = \)の平均最終最大総移動距離、垂直および水平表す)、又は移動しません。
数据范围:\(1 \ nは、M \ 200 \)、\ (1 \ K \ 200 \)、\ (1 \ S_I \ T_I \ 4 \ 4回10 ^ \) 。
非常に問題なくご質問、癌であることを示し、実際には、物語の活発な、巧妙なアプローチサブジェクト、コード長が興味深いです。パーフェクトああ!でも、私の小さなこんにゃくは除いて、一回限りです(\ texttt {ベクトル} \ \ ) いくつかのマイナーな問題です。
継続するには
#include <bits/stdc++.h>
using namespace std;
//Start
#define re register
#define il inline
#define mk make_pair
#define mt make_tuple
#define pb push_back
#define db double
#define lng long long
#define fi first
#define se second
const int inf=0x3f3f3f3f;
//Data
const int N=200;
int n,m,x,y,k,G[N+7][N+7];
vector<pair<int,int>> Mv;
int f[2][N+7][N+7];
char s[N+7];
//Main
int main(){
scanf("%d%d%d%d%d",&n,&m,&x,&y,&k);
for(re int i=1;i<=n;i++){
scanf("%s",s+1);
for(re int j=1;j<=m;j++) G[i][j]=(s[j]=='x');
}
for(re int i=1,s,t,d;i<=k;i++){
scanf("%d%d%d",&s,&t,&d);
Mv.pb(mk(d,t-s+1));
}
re int p=0,l,r;
re vector<int> q(max(n,m)+7);
for(re int i=1;i<=n;i++)
for(re int j=1;j<=m;j++) f[p][i][j]=-inf;
f[p][x][y]=0;
for(re auto mv:Mv){
p^=1;
for(re int i=1;i<=n;i++)
for(re int j=1;j<=m;j++) f[p][i][j]=-inf;
if(mv.fi==1){
for(re int j=1;j<=m;j++){
l=1,r=0;
for(re int i=n;i>=1;i--){
if(G[i][j]){l=r+1;continue;}
while(l<=r&&q[l]>i+mv.se) l++;
while(l<=r&&f[p^1][q[r]][j]+q[r]<=f[p^1][i][j]+i) r--;
q[++r]=i,f[p][i][j]=max(f[p][i][j],f[p^1][q[l]][j]+q[l]-i);
}
}
} else if(mv.fi==2){
for(re int j=1;j<=m;j++){
l=1,r=0;
for(re int i=1;i<=n;i++){
if(G[i][j]){l=r+1;continue;}
while(l<=r&&q[l]<i-mv.se) l++;
while(l<=r&&f[p^1][q[r]][j]-q[r]<=f[p^1][i][j]-i) r--;
q[++r]=i,f[p][i][j]=max(f[p][i][j],f[p^1][q[l]][j]+i-q[l]);
}
}
} else if(mv.fi==3){
for(re int i=1;i<=n;i++){
l=1,r=0;
for(re int j=m;j>=1;j--){
if(G[i][j]){l=r+1;continue;}
while(l<=r&&q[l]>j+mv.se) l++;
while(l<=r&&f[p^1][i][q[r]]+q[r]<=f[p^1][i][j]+j) r--;
q[++r]=j,f[p][i][j]=max(f[p][i][j],f[p^1][i][q[l]]+q[l]-j);
}
}
} else if(mv.fi==4){
for(re int i=1;i<=n;i++){
l=1,r=0;
for(re int j=1;j<=m;j++){
if(G[i][j]){l=r+1;continue;}
while(l<=r&&q[l]<j-mv.se) l++;
while(l<=r&&f[p^1][i][q[r]]-q[r]<=f[p^1][i][j]-j) r--;
q[++r]=j,f[p][i][j]=max(f[p][i][j],f[p^1][i][q[l]]+j-q[l]);
}
}
}
}
re int ans=-inf;
for(re int i=1;i<=n;i++)
for(re int j=1;j<=m;j++) ans=max(ans,f[p][i][j]);
printf("%d\n",ans);
return 0;
}
私はあなたに幸せな学習をしたいです!