luoguP2254 [NOI2005]瑰丽华尔兹

题目比较好,人比较菜。。。

#include<bits/stdc++.h>
#define MAXN 205
using namespace std;

int n,m,X,Y,K,f[MAXN][MAXN][MAXN],L,R,D,dx[7] = {0 , 1 , -1 , 0 , 0} , dy[7] = {0 , 0 , 0 , 1 , -1},l,r,q[MAXN],ans = 0;
char tu[MAXN][MAXN];

int main(){
	cin>>n>>m>>X>>Y>>K;
	for(int i = 1 ; i <= n ; i++){
		for(int j = 1 ; j <= m ; j++){
			cin>>tu[i][j];
		}
	}
	memset(f , -0x3f , sizeof(f));
	f[0][X][Y] = 0;
	for(int cishu = 1 ; cishu <= K ; cishu++){
		cin>>L>>R>>D;
		if(D == 1){
			for(int j = 1 ; j <= m ; j++){
				l = 0 , r = (-1);
				for(int i = n ; i >= 1 ; i--){
					if(tu[i][j] == 'x'){l = 0 , r = (-1);continue;}
					f[cishu][i][j] = f[cishu - 1][i][j];
					while(l <= r && q[l] - i > (R - L + 1))l++;
					while(l <= r && f[cishu - 1][q[r]][j] + q[r] < f[cishu - 1][i][j] + i)r--;
					q[++r] = i;
					if(l <= r)f[cishu][i][j] = max(f[cishu][i][j] , f[cishu - 1][q[l]][j] + q[l] - i);
					ans = max(ans , f[cishu][i][j]);
				}
			}	
		}
		else if(D == 2){
			for(int j = 1 ; j <= m ; j++){
				l = 0 , r = (-1);
				for(int i = 1 ; i <= n ; i++){
					if(tu[i][j] == 'x'){l = 0 , r = (-1);continue;}
					f[cishu][i][j] = f[cishu - 1][i][j];
					while(l <= r && i - q[l] > (R - L + 1))l++;
					while(l <= r && f[cishu - 1][q[r]][j] - q[r] < f[cishu - 1][i][j] - i)r--;
					q[++r] = i;
					if(l <= r)f[cishu][i][j] = max(f[cishu][i][j] , f[cishu - 1][q[l]][j] + i - q[l]);
					ans = max(ans , f[cishu][i][j]);
				}
			}	
		}
		else if(D == 3){
			for(int i = 1 ; i <= n ; i++){
				l = 0 , r = (-1);
				for(int j = m ; j >= 1 ; j--){
					if(tu[i][j] == 'x'){l = 0 , r = (-1);continue;}
					while(l <= r && q[l] - j > (R - L + 1))l++;
					while(l <= r && f[cishu - 1][i][q[r]] + q[r] < f[cishu - 1][i][j] + j)r--;
					q[++r] = j;
					if(l <= r)f[cishu][i][j] = max(f[cishu][i][j] , f[cishu - 1][i][q[l]] + q[l] - j);
					ans = max(ans , f[cishu][i][j]);
				}
			}
		}
		else if(D == 4){
			for(int i = 1 ; i <= n ; i++){
				l = 0 , r = (-1);
				for(int j = 1 ; j <= m ; j++){
					if(tu[i][j] == 'x'){l = 0 , r = (-1);continue;}
					while(l <= r && j - q[l] > (R - L + 1))l++;
					while(l <= r && f[cishu - 1][i][q[r]] - q[r] < f[cishu - 1][i][j] - j)r--;
					q[++r] = j;
					if(l <= r)f[cishu][i][j] = max(f[cishu][i][j] , f[cishu - 1][i][q[l]] + j - q[l]);
					ans = max(ans , f[cishu][i][j]);
				}
			}
		}
	}
	cout<<ans<<endl;
}

一开始看到平面图上dp,直接慌了。。。
但其实50分的dp方程非常好写
在加点优化,就可以有60分的好成绩

然后直接上单调队列了

这个部分

f[cishu - 1][i][q[r]] - q[r] < f[cishu - 1][i][j] - j

不要像我一样写成

f[cishu - 1][i][q[r]] - q[r] < f[cishu - 1][i][j]

。。。。
不然就会自闭

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值