洛谷P1434例题分析

[SHOI2002] 滑雪

题目描述

Michael 喜欢滑雪。这并不奇怪,因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael 想知道在一个区域中最长的滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子:

1   2   3   4   5
16  17  18  19  6
15  24  25  20  7
14  23  22  21  8
13  12  11  10  9

一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度会减小。在上面的例子中,一条可行的滑坡为 \(24\)\(17\)\(16\)\(1\)(从 \(24\) 开始,在 \(1\) 结束)。当然 \(25\)\(24\)\(23\)\(\ldots\)\(3\)\(2\)\(1\) 更长。事实上,这是最长的一条。

输入格式

输入的第一行为表示区域的二维数组的行数 \(R\) 和列数 \(C\)。下面是 \(R\) 行,每行有 \(C\) 个数,代表高度(两个数字之间用 \(1\) 个空格间隔)。

输出格式

输出区域中最长滑坡的长度。

样例输入

5 5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9

样例输出

25

例题分析

记忆化搜索模板题,任意路径上若已被搜索过,直接引用之前的答案(另开一个ans[][]数组存答案)不需要用bool 型数组标记,因为可能出现“环”的情况
在这里插入图片描述
例如从25->24->23->22是一条可行路线,而25->22也是一条路线,无论BFS还是DFS,25->22始终先被搜索,则25->24->23->22路线不通。

AC代码

#include<bits/stdc++.h>
using namespace std;
int r,c,mapp[110][110],v[110][110],ans[110][110],dx[5]={0,-1,0,1,0},dy[5]={0,0,1,0,-1},a[10010],b[10010];//打表
int main(){
	cin>>r>>c;
	for(int i=1;i<=r;i++){
		for(int j=1;j<=c;j++){
			cin>>mapp[i][j];
		}
	}
	for(int i=1;i<=r;i++){
		for(int j=1;j<=c;j++){
			memset(v,0,sizeof(v));
			memset(a,0,sizeof(a));
			memset(b,0,sizeof(b));//BFS广搜代码
			int left=1,right=1;
			a[1]=i;
			b[1]=j;
			v[i][j]=1;
			while(left<=right){
				int x=a[left],y=b[left++];
				for(int k=1;k<=4;k++){
					int nx=x+dx[k],ny=y+dy[k];
					if(nx>0&&nx<r+1&&ny>0&&ny<c+1&&mapp[nx][ny]<mapp[x][y]){
						if(ans[nx][ny]!=0){
							v[nx][ny]=v[x][y]+ans[nx][ny];//用当前点加上ans中已保存点,剪枝后可以不再重复遍历
							//因为ans中存储的答案一定是已经搜索过而得出的最长路径长度,所以不必考虑其他路线
						}
						else{
							a[++right]=nx;
							b[right]=ny;
							v[nx][ny]=v[x][y]+1;
						}
					}
				}
			}
			int maxn=0;
			for(int p=1;p<=r;p++){
				for(int q=1;q<=c;q++){
					if(v[p][q]>maxn)	maxn=v[p][q];//寻找最长路径并记录
				}
			}
			ans[i][j]=maxn;
		}
	}
	int maxnn=0;
	for(int i=1;i<=r;i++){
		for(int j=1;j<=c;j++){
			if(ans[i][j]>maxnn)	maxnn=ans[i][j];//在答案中再次搜索得出最优解
		}
	}
	cout<<maxnn;
	return 0;
}
posted @ 2022-11-09 16:28  Nebulary  阅读(41)  评论(0编辑  收藏  举报