一、问题描述

滑雪中,为了获得速度,滑的区域必须向下倾斜,现在想知道一个区域中的最长滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子

1 2 3 4  5   一个人可以从某个点滑向上下左右相邻四个点之一,当且仅
16 17 18 19 6  
当高度减小。在上面的例子中,一条可滑行的滑坡为:
15 24 25 20 7   24-17-16-1
。当然25-24-23-...-3-2-1更长。
14 23 22 21 8  
事实上,这是最长的一条。
13 12 11 10 9

输入:

输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C个整数,代表高度h0<=h<=10000

输出:

输出最长区域的长度。

 

二、解题思路

定义m[i][j]表示从点(i,j)为起点滑行的最大长度。滑行时,选择周围可以滑行的且m值最大的方向滑行。如果(i,j)的四个相邻元素都存在的话,则可以得到如下递归式(如图1)

m[i][j]=Max(m[i][j-1],m[i][j+1],m[i-1][j],m[i+1][j]) +1

通过递归地计算m[i][j-1],m[i][j+1],m[i-1][j]m[i+1][j]的值,找中四个中最大的一个,即是下一步滑行的位置,以此递归,直到不能继续滑行时返回。求解过程中,每求解到一个点的最大滑行长度则保存在数组m[i][j]中,因此不会重复求解同一个点的最大滑行长度。

用两重循环搜索整个矩阵中m[i][j]最大的点,m[i][j]就是要求解的最长区域的长度。

 

 

i-1,j

 

i,j-1

i,j

i,j+1

 

i+1,j

 

1

三、算法效率

时间复杂度0(n2),空间复杂度0(n2)

四、源代码

 1#include <iostream>
 2using namespace std;
 3int h[101][101];
 4int m[101][101];
 5int r,c;
 6int GetHigh(int i,int j)
 7{    
 8    
 9    if(m[i][j]!=-1)
10        return m[i][j];
11    else
12    {
13        int max=0;
14        int temp;
15        if(j>1)
16        {
17            if(h[i][j]>h[i][j-1])
18            {
19                temp=GetHigh(i,j-1);
20                if(max<temp)
21                    max=temp;
22            }

23        }

24        if(j<c)
25        {
26            if(h[i][j]>h[i][j+1])
27            {
28                temp=GetHigh(i,j+1);
29                if(max<temp)
30                    max=temp;
31            }

32        }

33        if(i>1)
34        {
35            if(h[i][j]>h[i-1][j])
36            {
37                temp=GetHigh(i-1,j);
38                if(max<temp)
39                    max=temp;
40            }

41        }

42        if(i<r)
43        {
44            if(h[i][j]>h[i+1][j])
45            {
46                temp=GetHigh(i+1,j);
47                if(max<temp)
48                    max=temp;
49            }

50        }

51        m[i][j]=max+1;
52        return m[i][j];
53    }

54
55}

56int main()
57{
58    int i,j;
59    int Max=-1;
60    int temp;
61    cin>>r>>c;
62    for(i=1;i<=r;i++)
63        for(j=1;j<=c;j++)
64            cin>>h[i][j];
65    for(i=1;i<=r;i++)
66        for(j=1;j<=c;j++)
67            m[i][j]=-1;
68    for(i=1;i<=r;i++)
69    {
70        for(j=1;j<=c;j++)
71        {
72            temp=GetHigh(i,j);
73            if(Max<temp)
74                Max=temp;    
75        }

76    }

77    cout<<Max<<endl;
78    return 1;
79
80        
81}