Solution to a problem - [NOI2005] magnificent waltz

Solution to a problem - [NOI2005] magnificent waltz

[NOI2005] magnificent waltz

\ (n \ times m \) matrix. With \ ((x, y) \ ) as a starting point. Total \ (K \) period of time, each time \ ([S_I, t_i] (+ t_i. 1. 1 + = S_ {I}) \) , the second can (D_i \) \ direction of movement of a unit ( not beyond the matrix, we can not come to an obstacle at a given matrix , \ (D = \ {1,2,3,4 \} \) represent vertical and horizontal), or does not move, averages the last maximum total movement distance.

数据范围: \ (1 \ n, m \ the 200 \) , \ (1 \ k \ the 200 \) , \ (1 \ the s_i \ the t_i \ 4 \ 4 times 10 ^ \) .


Very intriguing a question, indicating that the cancer is, in fact, the story lively, clever approach the subject, the code length without trouble. Perfect ah! Even my little konjac are one-off, except in \ (\ texttt {vector} \ ) is some minor problems.


To be continued


#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;
}

I wish you happy learning!

Guess you like

Origin www.cnblogs.com/Wendigo/p/12584836.html