题目链接: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 }
完。