1. 程式人生 > >洛谷P1434滑雪(逆向圖的遍歷dfs+記憶化)

洛谷P1434滑雪(逆向圖的遍歷dfs+記憶化)

題目連結:https://www.luogu.org/problemnew/show/P1434

 

剛開始最先想到的就是正向遞迴遍歷,遍歷所有情況方法,記錄找到最長的,正向遞迴遍歷也不難寫,但會超時。

觀察後,發現它是有規律的,或者說已經遍歷過的點需要多次用到,那就逆向記憶化。

注意:

圖的遍歷,標記陣列特例情況,走過了還會回去!
2 3
3 2 4
0 1 5

 

正向遞迴遍歷

 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <iomanip>
 5
#include <cstdio> 6 #include <cstring> 7 #include <cmath> 8 using namespace std; 9 typedef long long ll; 10 typedef unsigned long long ull; 11 const int maxn=105; 12 int a[maxn][maxn]; 13 int vis[maxn][maxn]; 14 int n,m; 15 int ans; 16 17 void so(int x,int y,int step)//這題不用標記陣列,>關係決定了不會回去死迴圈
18 { 19 if(step>ans) ans=step; 20 21 // 22 if(y+1<=m && a[x][y]<a[x][y+1]) { so(x,y+1,step+1); } 23 // 24 if(x+1<=n && a[x][y]<a[x+1][y]) { so(x+1,y,step+1); } 25 // 26 if(x-1>=1 && a[x][y]<a[x-1][y]) { so(x-1,y,step+1); } 27 //
28 if(y-1>=1 && a[x][y]<a[x][y-1]) { so(x,y-1,step+1); } 29 } 30 31 int main() 32 { 33 ios::sync_with_stdio(false); cin.tie(0); 34 35 cin>>n>>m; 36 for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>a[i][j]; 37 38 for(int i=1;i<=n;i++) 39 { 40 for(int j=1;j<=m;j++) 41 { 42 so(i,j,1); 43 } 44 } 45 46 cout<<ans<<endl; 47 48 return 0; 49 }

 

逆向遞迴遍歷+記憶化

 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <iomanip>
 5 #include <cstdio>
 6 #include <cstring>
 7 #include <cmath>
 8 using namespace std;
 9 typedef long long ll;
10 typedef unsigned long long ull;
11 const int maxn=105;
12 int a[maxn][maxn];
13 int Ans[maxn][maxn];
14 int n,m;
15 
16 int so(int x,int y)//這題不用標記陣列,>關係決定了不會回去死迴圈
17 {
18     if(Ans[x][y]) return Ans[x][y];
19 
20     int ans=1,a1=0,a2=0,a3=0,a4=0;
21     //
22     if(y+1<=m && a[x][y]>a[x][y+1]) a1=so(x,y+1)+1;
23     //
24     if(x+1<=n && a[x][y]>a[x+1][y]) a2=so(x+1,y)+1;
25     //
26     if(x-1>=1 && a[x][y]>a[x-1][y]) a3=so(x-1,y)+1;
27     //
28     if(y-1>=1 && a[x][y]>a[x][y-1]) a4=so(x,y-1)+1;
29 
30     ans=max(ans,a1);
31     ans=max(ans,a2);
32     ans=max(ans,a3);
33     ans=max(ans,a4);
34 
35     Ans[x][y]=max(Ans[x][y],ans);
36     return Ans[x][y];
37 }
38 
39 int main()
40 {
41     ios::sync_with_stdio(false); cin.tie(0);
42 
43     cin>>n>>m;
44     for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>a[i][j];
45 
46     int t=0;
47     for(int i=1;i<=n;i++)
48     {
49         for(int j=1;j<=m;j++)
50         {
51             t=max(t,so(i,j));
52         }
53     }
54 
55     cout<<t<<endl;
56 
57     return 0;
58 }

 

完。