数据结构与算法34-滑雪

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

Input
多组数据
输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。
接下来R行,每行有C个整数,代表高度h,0<=h<=10000。

Output
输出最长区域的长度。

Sample Input

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

Sample Output

25

参考程序(Python实现)

while True:
    try:
        R, C = map(int, input().split())
        mat = []  # 高度矩阵
        dic = {}  # 记录每一个高度在矩阵中的位置
        ele_list = []  # 所有高度组成的列表
        solution = []  # 解矩阵 表示到达 (i,j)后得到的最长路径
        for i in range(R):
            line = list(map(int, input().split()))
            solution.append([1 for j in range(C)])  # 解矩阵初始化为1
            mat.append(line[:])
            for j in range(C):
                ele_list.append(line[j])
                if line[j] not in dic:
                    dic[line[j]] = [(i, j)]
                else:
                    dic[line[j]].append((i, j))
        max_solution = 1
        ele_list.sort(reverse=True)
        for height in ele_list:  # 取出所有高度
            for pos in dic[height]:  # 取出这一高度对应的位置坐标(可能有多个)
                tmp = solution[pos[0]][pos[1]]  # 暂存当前解
                if pos[0] - 1 >= 0:  # have up
                    if mat[pos[0] - 1][pos[1]] > height and solution[pos[0] - 1][pos[1]] >= tmp:
                        tmp = solution[pos[0] - 1][pos[1]] + 1
                if pos[0] + 1 < R:  # have down
                    if mat[pos[0] + 1][pos[1]] > height and solution[pos[0] + 1][pos[1]] >= tmp:
                        tmp = solution[pos[0] + 1][pos[1]] + 1
                if pos[1] - 1 >= 0:  # have left
                    if mat[pos[0]][pos[1] - 1] > height and solution[pos[0]][pos[1] - 1] >= tmp:
                        tmp = solution[pos[0]][pos[1] - 1] + 1
                if pos[1] + 1 < C:  # have right
                    if mat[pos[0]][pos[1] + 1] > height and solution[pos[0]][pos[1] + 1] >= tmp:
                        tmp = solution[pos[0]][pos[1] + 1] + 1
                solution[pos[0]][pos[1]] = tmp
                if solution[pos[0]][pos[1]] > max_solution:  # 求出解矩阵中的最大解
                    max_solution = solution[pos[0]][pos[1]]

        print(max_solution)
    except:
        break

分析:
本题属于动态规划的问题,求解动态规划问题一是要找出最“基础”的情况,也就是最简单、最好处理的一种情况;二是要找出能够自底向上的递推关系。本题中的“基础情况”并不是矩阵的边界点,原因是题目没有说明从哪里出发到哪里结束,所以不能思维定式。在本题中,当在最高点处,因为不可能从其他点到达该处,所以到达该点的路径最大长度就是1.到达较高的点A的路径确定了,次高的点才有可能由此确定。考虑到自底向上的思想,这道题的“底”就是最高点,可以直接确定;“上”就是最后才计算的最低点。所以需要对高度进行排序,然后一个一个计算。在计算时需要定位到这个高度在矩阵的位置,便于找到上下左右四个邻居(如果存在的话),所以需要设置一个字典存储每个高度的位置(字典结构是,键:高度;值:位置列表。考虑可能有高度相同的点)

用Python语言刷题要做好编程难度和时间效率的权衡。Python数据结构丰富、常用操作集成较好,所以在问题的表示和抽象上很有优势,写出的程序很简洁。但是在运行时间上却是C语言的10倍,空间占用也较多。所以在语言选择上要综合考虑问题的复杂度和题目对时空效率的要求。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值