📅  最后修改于: 2023-12-03 15:27:35.866000             🧑  作者: Mango
给定一个 N 行 M 列的矩阵,每个元素都是一个非负整数。从左上角出发,只能朝右或者朝下走,最终到达右下角的位置,求路径上所有元素的乘积的最大值。
注意:要求路径上的乘积必须是非负数。
本题可以使用动态规划的思路来解决。
定义一个二维数组 dp[N][M]
,其中 dp[i][j]
表示从左上角到矩阵中第 i 行第 j 列位置的最大非负乘积。注意,这里使用了“最大非负乘积”来解决乘积为负数的情况。因为乘积为负数时,我们需要回退到上一个点重新开始计算。
那么,对于 dp[i][j]
来说,可以分为两种情况:
当 i == 0 && j == 0
时,即到达左上角的位置,其最大非负乘积为矩阵中第一个元素的值,即 dp[0][0] = matrix[0][0]
。
当 i == 0 && j != 0
时,即到达第一行的某一个位置。此时,只能从左边的位置过来,因此 dp[i][j] = dp[i][j-1] * matrix[i][j]
。
当 i != 0 && j == 0
时,即到达第一列的某一个位置。此时,只能从上边的位置过来,因此 dp[i][j] = dp[i-1][j] * matrix[i][j]
。
当 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
。