洛谷P1434滑雪(逆向圖的遍歷dfs+記憶化)
阿新 • • 發佈:2018-11-10
題目連結: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 }
完。