题目
滑雪的场地都是从高地势到低地势,现在陆历川在一块滑雪场,现在他想知道他在哪一个地方开始滑雪可以滑的距离最长,注意,必须从高的地势向低的地势走
输入
第一行两个数n,m代表矩阵的大小
接下来n行,每行m个数,数组中每个数字代表点的高度
输出
最长的滑行距离
样例输入
5 5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
样例输出
25
解题思路
递归,记忆化搜索
遍历每个点,利用记忆化,记录下每个点的最长距离,下次递归时直接使用。
注意一下递归函数的写法
代码
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std ;
const int maxn = 1000 + 10 ;
int d[maxn][maxn] ;
int dis[maxn][maxn] ;
int n , m ;
int u[4][2] = {0 , 1 , 1 , 0 , -1 , 0 , 0 , -1} ;
inline bool check(int x , int y)
{
if(x < 1 || x > n || y < 1 || y > m)
return false ;
return true ;
}
int findlen(int x , int y)
{
if(dis[x][y])
return dis[x][y] ;
int a , b ;
int t = 1 ;
for(int q = 0 ; q < 4 ; q++)
{
/// printf("now (%d , %d) " ,x , y) ;
a = x + u[q][0] ;
b = y + u[q][1] ;
if(check(a , b) == 1)
{
/// printf("in (%d ,%d) \n" , a , b) ;
if(d[x][y] >= d[a][b])
{
t = max(t , findlen(a , b) + 1) ;
}
}
}
dis[x][y] = max(t , dis[x][y]) ;
return dis[x][y] ;
}
int main()
{
while(scanf("%d%d" , &n , &m) != EOF)
{
memset(d , 0 , sizeof(d)) ;
memset(dis , 0 , sizeof(dis)) ;
for(int i = 1 ; i <= n ; i++)
{
for(int j = 1 ; j <= m ;j++)
scanf("%d" , &d[i][j]) ;
}
int ans = 0 ;
for(int i = 1 ; i <= n ; i++)
for(int j = 1 ; j<= m ;j++)
{
ans = max(ans , findlen(i , j)) ;
/// printf("(%d , %d) \n max : %d \n" , i , j , ans) ;
}
printf("%d\n" , ans) ;
}
return 0 ;
}
/*
5 5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
*/