# 1594. Maximum Non Negative Product in a Matrix ###### tags: `Leetcode` `Medium` `Dynamic Programming` Link: https://leetcode.com/problems/maximum-non-negative-product-in-a-matrix/ ## 思路 也是一道dp迷宫题 和[0152. Maximum Product Subarray](https://hackmd.io/qpgZUbERQVOXcw9DSBI1Mw)有点像 和传统的最优路径题一样,令```dp[i][j]```表示从左上角走到```(i,j)```的最优代价(即路径乘积最大)。根据规则,```dp[i][j]```仅由```dp[i-1][j]```和```dp[i][j-1]```转移而来。但是不同于以往的套路: ``` dp[i][j] = max(dp[i][j-1]*nums[i][j], dp[i-1][j]*nums[i][j]) ``` 在这里,如果```nums[i][j]```为负数的话,我们希望已知的反而是走到```(i-1,j)```和```(i,j-1)```的最小乘积路径,这样与```nums[i][j]```相乘之后才能得到的是最大乘积路径。这就提醒我们要维护两个状态变量,```dpMax[i][j]```和```dpMin[i][j]```来分别记录到当前的最大乘积路径和最小乘积路径。 ``` dp1[i][j] = max(max(dpMax[i][j-1]*nums[i][j], dpMax[i-1][j]*nums[i][j]), max(dpMin[i][j-1]*nums[i][j], doMin[i-1][j]*nums[i][j])); dp2[i][j] = min(min(dpMax[i][j-1]*nums[i][j], dpMax[i-1][j]*nums[i][j]), min(dpMin[i][j-1]*nums[i][j], dpMin[i-1][j]*nums[i][j])); ``` ## Code ```java= class Solution { public int maxProductPath(int[][] grid) { int m = grid.length, n = grid[0].length; long[][] dpMax = new long[m][n]; long[][] dpMin = new long[m][n]; int mod = 1000000007; for(int i=0; i<m; i++){ for(int j=0; j<n; j++){ if(i==0 && j==0){ dpMax[0][0] = grid[0][0]; dpMin[0][0] = grid[0][0]; } else if(i==0){ dpMax[i][j] = Math.max(dpMax[i][j-1]*grid[i][j], dpMin[i][j-1]*grid[i][j]); dpMin[i][j] = Math.min(dpMax[i][j-1]*grid[i][j], dpMin[i][j-1]*grid[i][j]); } else if(j==0){ dpMax[i][j] = Math.max(dpMax[i-1][j]*grid[i][j], dpMin[i-1][j]*grid[i][j]); dpMin[i][j] = Math.min(dpMax[i-1][j]*grid[i][j], dpMin[i-1][j]*grid[i][j]); } else{ dpMax[i][j] = Math.max(Math.max(dpMax[i-1][j]*grid[i][j], dpMin[i-1][j]*grid[i][j]), Math.max(dpMax[i][j-1]*grid[i][j], dpMin[i][j-1]*grid[i][j])); dpMin[i][j] = Math.min(Math.min(dpMax[i-1][j]*grid[i][j], dpMin[i-1][j]*grid[i][j]), Math.min(dpMax[i][j-1]*grid[i][j], dpMin[i][j-1]*grid[i][j])); } } } return dpMax[m-1][n-1]<0?-1:(int)(dpMax[m-1][n-1]%mod); } } ```