題目
滑雪的場地都是從高地勢到低地勢,現在陸歷川在一塊滑雪場,現在他想知道他在哪一個地方開始滑雪可以滑的距離最長,注意,必須從高的地勢向低的地勢走
輸入
第一行兩個數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
*/