洛谷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   } 

 

posted @ 2022-02-15 22:32  江上舟摇  阅读(34)  评论(0)    收藏  举报