Given an M × N matrix of integers where each cell has a cost associated with it, find the minimum cost to reach the last cell (M-1, N-1) of the matrix from its first cell (0, 0). We can only move one unit right or one unit down from any cell, i.e., from cell (i, j), we can move to (i, j+1) or (i+1, j).

For example,

Minimum cost path in a matrix

The highlighted path shows the minimum cost path having a cost of 36.
 

Practice this problem

 
The idea is to use recursion. The problem has optimal substructure. That means the problem can be broken down into smaller, simple “subproblems”, which can further be divided into yet simpler, smaller subproblems until the solution becomes trivial. We can recursively define the problem as:

Cost to reach cell (m, n) = cost[m][n] + min (cost to reach cell (m, n-1),
                                            cost to reach cell (m, n-1))

Following is the C++, Java, and Python implementation of the idea:

C++


Download  Run Code

Output:

The minimum cost is 36

Java


Download  Run Code

Output:

The minimum cost is 36

Python


Download  Run Code

Output:

The minimum cost is 36

The time complexity of the proposed solution is exponential as we are doing a lot of redundant work. For example, consider the recursion tree for a 5 × 5 matrix.

LRS

 
As we can see, the same subproblems (highlighted in the same color) are getting computed repeatedly. As the recursion grows deeper, more and more of this type of unnecessary repetition occurs. We know that problems having optimal substructure and overlapping subproblems can be solved by dynamic programming, in which subproblem solutions are memoized rather than computed repeatedly. Each time we calculate the minimum cost of reaching any cell (i, j), we save it. If we are ever asked to compute it again, give the saved answer and do not recompute it.

The following bottom-up approach computes, for each 0 <= i < M and 0 <= j < N, the minimum costs of reaching cell (i, j) from cell (0, 0), using the costs of smaller values i and j already computed. It has the same asymptotic runtime as Memoization but no recursion overhead.

Following is the C++, Java, and Python implementation of the idea:

C++


Download  Run Code

Output:

The minimum cost is 36

Java


Download  Run Code

Output:

The minimum cost is 36

Python


Download  Run Code

Output:

The minimum cost is 36

The time complexity of the proposed solution is O(M × N) for an M × N matrix. The auxiliary space required by the program is O(M × N).

 
Exercise: Extend the solution to consider diagonal moves as well.