解题思路:
如果从i,j可以顺着某侧滑的话:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 dp[i][j] = max{dp[i-1][j],dp[i][j-1],dp[i+1][j],dp[i][j+1]} + 1
那么我们可以写出以下递归:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 int dp(int i,int j) 2 { 3 for(i,j上侧,下侧,左侧,右侧) 4 if(该位置没有越界) 5 { 6 if(顺着该侧可以往下滑) 7 如果该侧位置可以滑行的距离(递归调用dp函数)大于dp[i][j],则把dp[i][j]改成该距离+1 8 } 9 }
所以依据上面的提示,就可以写出下面的代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<algorithm> 2 #include<cstdio> 3 #include<cstring> 4 #include<iostream> 5 using namespace std; 6 int r,c,map[105][105],dp[105][105]; 7 int dx[]={-1,1,0,0}; 8 int dy[]={0,0,-1,1}; 9 int DP(int x,int y) 10 { 11 if(dp[x][y]!=0) return dp[x][y]; 12 int MAX = 0; 13 for(int k=0;k<4;k++) 14 { 15 int nx = x+dx[k]; 16 int ny = y+dy[k]; 17 if(map[nx][ny]<map[x][y]&&nx>=1&&ny>=1&&nx<=r&&ny<=c){ 18 if(DP(nx,ny)>MAX) 19 MAX = DP(nx,ny); 20 } 21 } 22 dp[x][y] = MAX+1; 23 return dp[x][y]; 24 } 25 int main() 26 { 27 scanf("%d%d",&r,&c); 28 memset(dp,0,sizeof(dp)); 29 memset(map,0,sizeof(map)); 30 for(int i=1;i<=r;i++) for(int j=1;j<=c;j++) scanf("%d",&map[i][j]); 31 int MAX = 0; 32 for(int i=1;i<=r;i++) 33 { 34 for(int j=1;j<=c;j++) 35 { 36 if(DP(i,j)>MAX) 37 MAX = DP(i,j); 38 } 39 } 40 printf("%d",MAX); 41 }