📌  相关文章
📜  国际空间研究组织 | ISRO CS 2017 – 5 月 |问题 22(1)

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

国际空间研究组织-ISRO CS 2017 - 5月 - 问题22

题目描述

在一个Nxn的矩阵中,找到最短路径从第一行到最后一行。你只能向下移动,可以在同一列中随时改变方向,即从左到右或从右到左或直接向下。

输入
  • 一个整数T(1 <= T <= 100),表示测试用例的数量。
  • 对于每个测试用例:
    • 第一行包含整数N(1 <= N <= 1000)
    • 接下来N行,每行包含N个整数,表示Nxn的矩阵的元素。
输出

对于每个测试用例,输出一个整数,表示从第一行到最后一行的最短路径长度。

示例

输入:

2
5
1 2 3 4 5
5 4 3 2 1
7 8 9 1 2
6 5 4 3 2
1 1 1 1 1
3
3 3 3
1 1 1
3 3 3

输出:

8
3
思路

用动态规划来解决这个问题。

定义一个数组dp[1000][1000],其中dp[i][j]表示从第一行到第ji列的最小路径长度。

我们可以从上一行的所有列计算下一行的最小路径长度。通过逐行遍历来计算整个矩阵的最小路径长度。

例如,假设我们需要计算dp[3][4],我们可以看作是从左下方的位置、正下方的位置以及右下方的位置转移而来,找到最小的值,加上该位置的值。

实现时,我们可以先计算右下方和正下方的值来更新dp数组,然后再计算左下方的值,即可确保在更新每个位置的值时我们正在参考旧值。

代码
def is_valid(x, y, n):
    if 0 <= x < n and 0 <= y < n:
        return True
    return False

def min_path(n, arr):
    dp = [[0 for _ in range(n)] for _ in range(n)]
    for j in range(n):
        dp[0][j] = arr[0][j]

    for i in range(1, n):
        for j in range(n):
            dp[i][j] = dp[i - 1][j] + arr[i][j]
            if is_valid(i - 1, j - 1, n):
                dp[i][j] = min(dp[i][j], dp[i - 1][j - 1] + arr[i][j])
            if is_valid(i - 1, j + 1, n):
                dp[i][j] = min(dp[i][j], dp[i - 1][j + 1] + arr[i][j])

    return min(dp[n - 1]) # 返回最后一行的最小值

代码中的is_valid函数用于检查给定的坐标是否在矩阵范围内。

最后的min(dp[n - 1])返回最后一行的最小路径长度。