洛谷P1434 [SHOI2002]滑雪
阿新 • • 發佈:2022-02-15
題目連結: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 }