Given an M × N integer matrix where each cell has a non-negative cost associated with it, count the number of paths to reach the last cell (M-1, N-1) of the matrix from its first cell (0, 0) such that the path has given cost. 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, consider the following 4 × 4 matrix where cost is 25. Two paths are having a cost of 25.

Matrix path with given cost
 

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 follows:

path(m, n, cost) = path(m, n – 1, cost – M[m][n])    (if m == 0)
                 = path(m – 1, n, cost – M[m][n])    (if n == 0)
                 = path(m – 1, n, cost – M[m][n])
                 + path(m, n – 1, cost – M[m][n])    (otherwise)
 
path(0, 0, cost) = 1 (if M[m][n] == cost)
                 = 0 (otherwise)

Here, path(m, n, cost) represents the total number of paths to reach cell (m, n) from cell (0, 0) of the matrix M, and each path has cost cost.

The algorithm can be implemented as follows in C++, Java, and Python:

C++


Download  Run Code

Output:

Total paths with cost 25 are 2

Java


Download  Run Code

Output:

Total paths with cost 25 are 2

Python


Download  Run Code

Output:

Total paths with cost 25 are 2

The time complexity of the proposed solution is exponential as we are doing a lot of redundant work as the same subproblems are getting computed repeatedly. As the recursion grows deeper in bigger matrices, more and more 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 compute the total number of paths with cost c to reach any cell (i, j), save it. If we are ever asked to compute it again, give the saved answer and do not recompute it.

Following is the implementation in C++, Java, and Python based on the above idea:

C++


Download  Run Code

Output:

Total paths with cost 25 are 2

Java


Download  Run Code

Output:

Total paths with cost 25 are 2

Python


Download  Run Code

Output:

Total paths with cost $25 are 2

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

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