📌  相关文章
📜  给定矩阵从左上角到右下角的路径的最大非负乘积(1)

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

给定矩阵从左上角到右下角的路径的最大非负乘积

问题描述

给定一个 N 行 M 列的矩阵,每个元素都是一个非负整数。从左上角出发,只能朝右或者朝下走,最终到达右下角的位置,求路径上所有元素的乘积的最大值。

注意:要求路径上的乘积必须是非负数。

解题思路

本题可以使用动态规划的思路来解决。

定义一个二维数组 dp[N][M],其中 dp[i][j] 表示从左上角到矩阵中第 i 行第 j 列位置的最大非负乘积。注意,这里使用了“最大非负乘积”来解决乘积为负数的情况。因为乘积为负数时,我们需要回退到上一个点重新开始计算。

那么,对于 dp[i][j] 来说,可以分为两种情况:

  1. i == 0 && j == 0 时,即到达左上角的位置,其最大非负乘积为矩阵中第一个元素的值,即 dp[0][0] = matrix[0][0]

  2. i == 0 && j != 0 时,即到达第一行的某一个位置。此时,只能从左边的位置过来,因此 dp[i][j] = dp[i][j-1] * matrix[i][j]

  3. i != 0 && j == 0 时,即到达第一列的某一个位置。此时,只能从上边的位置过来,因此 dp[i][j] = dp[i-1][j] * matrix[i][j]

  4. i != 0 && j != 0 时,即到达其它位置。此时,可以从左边或上边的位置过来,因此 dp[i][j] 的值就是从左边或上边的值乘上当前位置的值,即 dp[i][j] = max(dp[i][j-1], dp[i-1][j]) * matrix[i][j]

最终,矩阵右下角的位置的值就是从左上角到右下角的最大非负乘积。

代码实现
def maxNonNegativeProduct(matrix):
    if not matrix:
        return 0
    n, m = len(matrix), len(matrix[0])
    dp = [[0] * m for _ in range(n)]
    dp[0][0] = matrix[0][0]
    for i in range(1, n):
        dp[i][0] = dp[i-1][0] * matrix[i][0]
    for j in range(1, m):
        dp[0][j] = dp[0][j-1] * matrix[0][j]
    for i in range(1, n):
        for j in range(1, m):
            dp[i][j] = max(dp[i-1][j], dp[i][j-1]) * matrix[i][j]
    return dp[n-1][m-1] if dp[n-1][m-1] >= 0 else -1

执行 maxNonNegativeProduct([[1, -2, 1], [1, -2, 1], [1, 1, 1]]) 的结果为 2