//pku1088 滑雪(记忆化搜索) /* 首先题目的意思不能弄错。问的是:每个点都有一个高度,而你滑雪肯定从高到底滑, 让你选择一个点,使得以这个点为起点的路径最长。 方法:记忆化搜索 单纯的搜索肯定耗时,所以就要将已经计算出来的值保存下来,下次如果要用调用一下计可以了。 */ #include<iostream> #include<cstdlib> #include<cstdio> #include<cmath> #include<algorithm> #include<vector> #include<string> #include<sstream> #include<set> #include<map> #include<queue> #include<stack> using namespace std; const int N=101; int F[N][N]; //F[i][j]表示已第i行第j列为起点所获得的最长路段 int mat[N][N]; int maxLength; int n,m; int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; bool canBe(int x,int y) { if(x>=0 && x<n && y>=0 && y<m) return true; else return false; } int getMax(int x,int y) { if(F[x][y]>1) return F[x][y]; //如果已计算过,直接调用,记忆化搜索关键 int i; for(i=0;i<4;i++) { int newX=x+dir[i][0]; int newY=y+dir[i][1]; if(canBe(newX,newY)) { if(mat[newX][newY]<mat[x][y]) { if(getMax(newX,newY) >= F[x][y]) F[x][y]=getMax(newX,newY)+1; } } } return F[x][y]; //如果四个方向没有比当前低的,就返回它本身的值。 } int main() { while(scanf("%d%d",&n,&m)!=EOF) { maxLength=INT_MIN/2; int i,j; for(i=0;i<n;i++) { for(j=0;j<m;j++) { scanf("%d",&mat[i][j]); F[i][j]=1; //初始化为1,自己这一个点算1步 } } for(i=0;i<n;i++) { for(j=0;j<m;j++) { F[i][j]=getMax(i,j); //cout<<F[i][j]<<" "; if(F[i][j]>maxLength) maxLength=F[i][j]; } //cout<<endl; } printf("%d/n",maxLength); } return 0; }