洛谷P1434 [SHOI2002]滑雪
题目链接:https://www.luogu.com.cn/problem/P1434
四联通问题和记忆化搜索的典型,如何会应用记忆化搜素呢?
在dfs每种情况是,可能这个点之前已经搜过了,没必要再去搜索了,因此不如存储记住,就没必要再去dfs了。
所以说,要进行dfs,就要定义方向,用一个dir[4][2]来表示上下左右四个方位
搜索的方向就是newx=x+dir[i][0]就好了,newy=y+dir[i][1]。
当然还要判断这个点是否能滑到,也就是高度要前一个低:
if(a[newx][newy]<a[x][y])
很明显,因为低的不可能滑向高的,所以我们不需要再开一个数组去记录这个点是否走过。
接下来,就要往四个方向搜索,取四个方向中距离最长的,然后+1,这就是这个点的结果了。
1 #include<bits/stdc++.h> 2 using namespace std; 3 int r,c; 4 int a[110][110]; 5 int ans; 6 int dp[110][110];//从(i,j)点出发能走的最长距离 7 #define CHECK(x,y)(x>=0&&x<r&&y>=0&&y<c) 8 int dir[4][2]={ 9 {-1,0},//左 10 {0,-1},//上 11 {1,0},//右 12 {0,1}//下 13 }; 14 int dfs(int x,int y) 15 { 16 int newx,newy;//新方位 17 if(dp[x][y]>0)//记忆化标记,如果被标记过了直接返回即可 18 return dp[x][y]; 19 dp[x][y]=1;//初始化 20 for(register int i=0;i<4;i++) 21 { 22 newx=x+dir[i][0];//对于横坐标的搜索 23 newy=y+dir[i][1];//对于纵坐标的搜索 24 if(CHECK(newx,newy)&&a[x][y]>a[newx][newy])//边界条件以及从高滑到低 25 { 26 dfs(newx,newy);//进入下一层搜索 27 dp[x][y]=max(dp[newx][newy]+1,dp[x][y]);//它的最长路径来自它的上下左右四边的最长的最长路+1 28 } 29 } 30 return dp[x][y]; 31 } 32 int main() 33 { 34 ios::sync_with_stdio(false); 35 cin>>r>>c; 36 for(register int i=0;i<r;i++) 37 { 38 for(register int j=0;j<c;j++) 39 { 40 cin>>a[i][j]; 41 } 42 } 43 for(register int i=0;i<r;i++) 44 { 45 for(register int j=0;j<c;j++) 46 { 47 ans=max(ans,dfs(i,j));////找从每个出发的最长距离 48 } 49 } 50 cout<<ans<<endl; 51 return 0; 52 }
本文来自博客园,作者:江上舟摇,转载请注明原文链接:https://www.cnblogs.com/LQS-blog/p/15898413.html

浙公网安备 33010602011771号