1. 程式人生 > 其它 >洛谷P1434 [SHOI2002]滑雪

洛谷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 }
戒驕戒躁,任重道遠