滑雪

问题

题目描述:

Michael 喜欢滑雪。这并不奇怪,因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael 想知道在一个区域中最长的滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子:

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

一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为 24-17-16-1 . 当然 25-24-23-...-3-2-1 更长。事实上,这是最长的一条.

输入描述:

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

输出描述:

输出最长区域的长度

样例输入:

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

思考

深度搜索,记忆化,递归。

废话两句
坦白地说,这题我并没怎么理解,很多都是参照题解的。😣😣😣

这道题和求解迷宫问题非常的相似,当然,这题比前者难度更高一些。

使用数组s[i][j]来记录起点为坐标(i,j)的元素的最长坡道长度,s[i][j]默认长度为1。

s[i][j]=max{s[i][j],s[dx][dy]+1}
s[dx][dy]为其s[i][j]可去的下一个元素的最长坡道长度。
有个疑惑,为什么要max{}呢?而不是直接s[i][j]=s[dx][dy]+1呢?

代码

点击查看代码
#include <iostream>
#include <algorithm>
using namespace std;
int R, C;
int arr[101][101];
int s[101][101];
int direct[] = {-1, 0, 1, 0, -1};
int fun(int x, int y);
int main()
{
    while (cin >> R >> C)
    {
        for (int i = 1; i < 1 + R; i++)
            for (int j = 1; j < 1 + C; j++)
                cin >> arr[i][j];

        int ans = -1;
        
        for (int i = 1; i <= R; i++)
            for (int j = 1; j <= C; j++)
            {
                if (ans < fun(i, j))
                    ans = fun(i, j);
            }
        cout << ans << endl;
    }
    return 0;
}

int fun(int x, int y)
{
    int dx, dy;
    s[x][y] = 1;
    for (int i = 0; i < 4; i++)
    {
        dx = x + direct[i], dy = y + direct[i + 1];
        if (dx > 0 && dy > 0 && dx < C + 1 && dy < R + 1 && arr[dx][dy] < arr[x][y])
        {
            fun(dx, dy);
            s[x][y] = max(s[x][y], s[dx][dy] + 1);
        }
    }
    return s[x][y];
}

posted @ 2022-03-21 16:47  请去看诡秘之主  阅读(35)  评论(1)    收藏  举报