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]

。。。。
不然就會自閉

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章