Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to find maximum non negative product in a matrix in Python
Finding the maximum non-negative product path in a matrix is a dynamic programming problem. We need to traverse from the top-left corner (0, 0) to the bottom-right corner (m-1, n-1), moving only right or down, while tracking both maximum and minimum products at each cell.
Problem Understanding
Given an m x n matrix, we need to find a path from top-left to bottom-right that maximizes the product of all elements along the path. Since negative numbers can become positive when multiplied by other negatives, we track both maximum and minimum values at each position.
For the example matrix:
| 2 | -4 | 2 |
| 2 | -4 | 2 |
| 4 | -8 | 2 |
The optimal path (highlighted) gives us: 2 × 2 × (-4) × (-8) × 2 = 256
Algorithm Steps
The solution uses dynamic programming where each cell stores a pair [maximum_product, minimum_product] representing the best and worst products achievable at that position:
- Initialize a DP table with the same dimensions as the input matrix
- For each cell, calculate products from both possible previous positions (above and left)
- Store both maximum and minimum values to handle negative multiplications
- Return the maximum product at the destination, or -1 if it's negative
Implementation
def solve(matrix):
p = int(1e9 + 7)
m = len(matrix)
n = len(matrix[0])
# DP table where each cell stores [max_product, min_product]
dp = [[0 for _ in range(n)] for _ in range(m)]
for i in range(m):
for j in range(n):
if i == 0 and j == 0:
# Base case: starting position
dp[i][j] = [matrix[i][j], matrix[i][j]]
elif i == 0:
# First row: can only come from left
product = dp[i][j-1][0] * matrix[i][j]
dp[i][j] = [product, product]
elif j == 0:
# First column: can only come from above
product = dp[i-1][j][0] * matrix[i][j]
dp[i][j] = [product, product]
else:
# Calculate all possible products from previous positions
from_above_max = dp[i-1][j][0] * matrix[i][j]
from_above_min = dp[i-1][j][1] * matrix[i][j]
from_left_max = dp[i][j-1][0] * matrix[i][j]
from_left_min = dp[i][j-1][1] * matrix[i][j]
# Find overall max and min
all_products = [from_above_max, from_above_min, from_left_max, from_left_min]
maximum = max(all_products)
minimum = min(all_products)
# Store appropriate values based on sign
if maximum < 0:
dp[i][j] = [minimum, minimum] # Both negative, choose larger
elif minimum > 0:
dp[i][j] = [maximum, maximum] # Both positive, choose larger
else:
dp[i][j] = [maximum, minimum] # Mixed signs, keep both
# Return result
if dp[m-1][n-1][0] < 0:
return -1
else:
return int(dp[m-1][n-1][0] % p)
# Test with the example matrix
matrix = [[2, -4, 2], [2, -4, 2], [4, -8, 2]]
result = solve(matrix)
print(f"Maximum non-negative product: {result}")
Maximum non-negative product: 256
Key Points
- Dynamic Programming: Each cell stores both maximum and minimum products to handle negative multiplications
- Path Constraints: Can only move right or down from any position
- Negative Handling: Two negatives multiply to positive, so we track both extremes
- Modulo Operation: Result is returned modulo 10^9+7 to handle large numbers
Time and Space Complexity
- Time Complexity: O(m × n) where m and n are matrix dimensions
- Space Complexity: O(m × n) for the DP table
Conclusion
This dynamic programming solution efficiently finds the maximum non-negative product path by tracking both maximum and minimum values at each position. The algorithm handles negative numbers correctly and returns -1 when no non-negative product path exists.
