📜  门| GATE-CS-2014-(Set-1) |问题 21(1)

📅  最后修改于: 2023-12-03 15:28:43.695000             🧑  作者: Mango

题目介绍

本题目为 2014 年 GATE-CS-SET-1 的第 21 道问题。该问题是一道算法题,需要使用动态规划的思想解决。

题目描述

给定一个 $n \times m$ 的矩阵,其中每个元素是一个非负整数。同时,给定两个点 $(x_1, y_1)$ 和 $(x_2, y_2)$。你需要找到从 $(x_1, y_1)$ 走到 $(x_2, y_2)$ 的路径,使得路径上的数值和最小。路径只能从一个点走到相邻(上、下、左、右)的点。

算法思路

本题可以使用动态规划的思想解决。我们设 $d_{i,j}$ 表示从点 $(x_1, y_1)$ 到点 $(i, j)$ 的最小数值和。因为每个点只能从相邻的点转移而来,所以 $d_{i,j}$ 可以由 $d_{i-1,j}$,$d_{i+1,j}$,$d_{i,j-1}$ 和 $d_{i,j+1}$ 转移而来。

具体而言,当计算 $d_{i,j}$ 时,我们可以从四个方向中选取一个值最小的。即:

$$ d_{i,j}=\min{d_{i-1,j},d_{i+1,j},d_{i,j-1},d_{i,j+1}} + matrix_{i,j} $$

由此,我们可以使用动态规划的思想逐一计算每个点的最小数值和。最终,$d_{x_2,y_2}$ 就是我们要查找的数值和。

代码实现

以下是 Python 实现的代码片段,用于计算 $d_{i,j}$:

def min_sum_matrix(matrix, x1, y1, x2, y2):
    n, m = len(matrix), len(matrix[0])
    d = [[float('inf')]*m for _ in range(n)]
    d[x1][y1] = matrix[x1][y1]
    for i in range(x1+1, x2+1):
        d[i][y1] = d[i-1][y1] + matrix[i][y1]
    for j in range(y1+1, y2+1):
        d[x1][j] = d[x1][j-1] + matrix[x1][j]
    for i in range(x1+1, x2+1):
        for j in range(y1+1, y2+1):
            d[i][j] = matrix[i][j] + min(d[i-1][j], d[i+1][j], d[i][j-1], d[i][j+1])
    return d[x2][y2]

该代码定义了一个名为 min_sum_matrix 的函数,可以接受一个矩阵 matrix 和两个坐标 (x1, y1)(x2, y2)。函数返回从点 (x1, y1) 到点 (x2, y2) 的最小数值和。该函数首先使用一个 $n \times m$ 的矩阵 d 来存储每个点的最小数值和。然后,它使用三个循环来计算每个点的最小数值和。在第一个循环中,使用 d[i-1][y1]matrix[i][y1] 进行初始化。在第二个循环中,使用 d[x1][j-1]matrix[x1][j] 进行初始化。在第三个循环中,使用动态规划的思想计算每个点的最小数值和。

总结

本题是一道经典的动态规划问题,可以使用动态规划的思想解决。需要注意的是,当计算 $d_{i,j}$ 时,需要使用四个方向中的最小值,才能得到正确的结果。除此之外,该问题还有一些变种和拓展,比如最大数值和路径问题,可以在动态规划的基础上进行扩展。