Suppose we have a 2D matrix with 3 possible values −
0 for an empty cell.
1 for a coin.
−1 for a wall.
We have to find the maximum number of coins we can take by starting from the top−left cell and reaching the bottom−right cell by moving only right or down direction. Then come back to the top−left cell by only moving up or left direction. When we pick up a coin, the cell value becomes 0. If we cannot reach the bottom−right cell, then return 0.
So, if the input is like
0 | 1 | 1 |
1 | 1 | 1 |
−1 | 1 | 1 |
0 | 1 | 1 |
then the output will be 8.
To solve this, we will follow these steps −
n := row count of mat, m := column count of mat
Define a function util() . This will take i, j, k, l
if i and j are not in range of mat or mat[i, j] is same as −1, then
return −inf
if k and l are not in range of mat or mat[k, l] is same as −1, then
return −inf
if i, j, k and l all are 0, then
return mat[0, 0]
best := −inf
for each pair (dx1, dy1) in [(−1, 0) ,(0, −1) ], do
for each pair (dx2, dy2) in [(−1, 0) ,(0, −1) ], do
best := maximum of best and util(i + dy1, j + dx1, k + dy2, l + dx2)
return mat[i, j] +(1 when i is not same as k, otherwise 0) * mat[k, l] + best
From the main method do the following −
return maximum of 0 and util(n − 1, m − 1, n − 1, m − 1)
Let us see the following implementation to get better understanding −
Example
class Solution: def solve(self, mat): n, m = len(mat), len(mat[0]) def util(i, j, k, l): if not (0 <= i < n and 0 <= j < m) or mat[i][j] == −1: return −1e9 if not (0 <= k < n and 0 <= l < m) or mat[k][l] == −1: return −1e9 if i == 0 and j == 0 and k == 0 and l == 0: return mat[0][0] best = −1e9 for dx1, dy1 in [(−1, 0), (0, −1)]: for dx2, dy2 in [(−1, 0), (0, −1)]: best = max(best, util(i + dy1, j + dx1, k + dy2, l + dx2)) return mat[i][j] + (i != k) * mat[k][l] + best return max(0, util(n − 1, m − 1, n − 1, m − 1)) ob = Solution() matrix = [ [0, 1, 1], [1, 1, 1], [1, −1, 1], [0, 1, 1] ] print(ob.solve(matrix))
Input
[ [0, 1, 1], [1, 1, 1], [1, −1, 1], [0, 1, 1] ]
Output
8