Open In App

# Minimize cost to reach bottom right from top left corner of Matrix with given separate cost for each move

Given an integer N and three N x N matrices X[][], Y[][], and Z[][], the task is to calculate the minimum cost required to reach the bottom right from the top left of the matrix using the following moves:

• Move to a cell in the right direction from (i, j) which will cost X[i][j].
• Move to a cell in the downward direction from (i, j) which will cost Y[i][j].
• Move to a cell in the diagonal direction from (i, j) which will cost Z[i][j],

Example:

Input: N = 3, X[][] = {{1, 2, 1}, {3, 4, 5}, {1, 1, 1}}, Y[][] = {{2, 3, 4}, {1, 3, 1}, {2, 1, 1}}, Z[][] = {{1, 8, 9}, {1, 4, 5}, {6, 5, 4}}.
Output: 4
Explanation: The path which will lead to the minimum cost is as follows:

• In first move, move downwards from (0, 0) to (1, 0) which will add a cost of 2.
• In second move, move diagonally from (1, 0) to (2, 1) which will add a cost of 1.
• In third and final move, move to the right from (2, 1) to (2, 2) which will add a cost of 1.

Therefore, the total required cost is 4, which is the minimum possible.

Input: N = 2, X[][] = {{1, 1}, {1, 1}}, Y[][] = {{1, 1}, {1, 1}}, Z[][] = {{1, 1}, {1, 1}}
Output: 1

Recursive Approach:

This approach to solve the problem is to move to cells recursively by moving in the three directions (right, down, diagonal) starting from top left cell untill reaches bottom right cell of the grid. If the current cell is the bottom right cell of the matrix, then the cost of reaching that cell is the cost of that cell itself. If the current cell is out of bounds of the matrix, then the cost of reaching that cell is infinite. If we are moving to right cell then add the cost of the current cell to the minimum cost required to reach the bottom right cell from the next cell in the right direction. If we are moving down, then add the cost of the current cell to the minimum cost required to reach the bottom right cell from the next cell in the down direction. If we are moving diagonally then add the cost of the current cell to the minimum cost required to reach the bottom right cell from the next cell in the diagonal direction. At the end of each recursion call, return the minimum of the three costs obtained from the three recursive calls made earlier.

Algorithm:

•    Define a recursive utility function called minCostUtil that takes X, Y, Z, i, and j as arguments.
•    Check if the current position is (0, 0), if so return 0.
•    Initialize a variable ans with a large value (e.g., INT_MAX).
•    If we can move to the left (j > 0), calculate the cost of moving to the left using the recursive call to minCostUtil and add X[i][j-1] to it.
•    If we can move to the top (i > 0), calculate the cost of moving to the top using the recursive call to minCostUtil and add Y[i-1][j] to it.
•    If we can move diagonally as well (i > 0 and j > 0), calculate the cost of moving diagonally using the recursive call to minCostUtil and add     Z[i-1][j-1] to it.
•    Return the minimum value of ans.
•    Define a function called minCost that takes X, Y, Z, and n as arguments.
•    Call minCostUtil with arguments n-1 and n-1 and return the result.

Below is the implementation of the above approach:

## C++

 `// C++ code for the approach` `#include ``#define R 3``#define C 3``using` `namespace` `std;` `// A utility function that returns``// minimum of 3 integers``int` `min(``int` `x, ``int` `y, ``int` `z)``{``    ``if` `(x < y)``        ``return` `(x < z) ? x : z;``    ``else``        ``return` `(y < z) ? y : z;``}` `// Recursive utility function``int` `minCostUtil(``int` `X[][C], ``int` `Y[][C], ``int` `Z[][C],``              ``int` `i, ``int` `j)``{``    ``// Base case``    ``if` `(i == 0 && j == 0)``        ``return` `0;` `    ``int` `ans = INT_MAX;` `    ``// If we can move to the left``    ``if` `(j > 0)``        ``ans = min(ans, minCostUtil(X, Y, Z, i, j - 1) + X[i][j - 1]);` `    ``// If we can move to the top``    ``if` `(i > 0)``        ``ans = min(ans, minCostUtil(X, Y, Z, i - 1, j) + Y[i - 1][j]);` `    ``// If we can move diagonally as well``    ``if` `(i > 0 && j > 0)``        ``ans = min(ans, minCostUtil(X, Y, Z, i - 1, j - 1) + Z[i - 1][j - 1]);` `    ``// Save the computed value and return it``    ``return` `ans;``}` `// Function to find the min cost path``int` `minCost(``int` `X[][C], ``int` `Y[][C], ``int` `Z[][C], ``int` `n)``{``    ``return` `minCostUtil(X, Y, Z, n - 1, n - 1);``}` `// Driver code``int` `main()``{``    ``int` `N = 3;``    ``int` `X[R][C] = {{1, 2, 1},``                ``{3, 4, 5},``                ``{1, 1, 1}};``    ``int` `Y[R][C] = {{2, 3, 4},``                ``{1, 3, 1},``                ``{2, 1, 1}};``    ``int` `Z[R][C] = {{1, 8, 9},``                ``{1, 4, 5},``                ``{6, 5, 4}};` `    ``cout << minCost(X, Y, Z, 3);` `    ``return` `0;``}` `// This code is contributed by Chandramani Kumar`

Output

`4`

Time Complexity: O(3^n), where n is the size of the matrix.
Space Complexity: O(1) as no extra space has been taken. Ignoring the recusrion stack space.

Approach: The given problem follows a similar structure to the standard Min Cost Path problem. It can be solved using dynamic programming. The path to reach (i, j) must be through one of the 3 cells: (i-1, j-1) or (i-1, j) or (i, j-1). So minimum cost to reach (i, j) can be written as the following relation:

minCost(i, j) = min ( minCost(i, j – 1) + X[i][j – 1],
minCost(i – 1, j) + Y[i – 1][j],
minCost(i – 1, j – 1) + Z[i – 1][j – 1])

Therefore, create a 2D array dp[][], where dp[i – 1][j – 1] stores the minimum cost to reach the cell (i, j) from (0, 0) and fill the dp[][] array in a bottom-up manner. The value stored at dp[N – 1][N – 1] is the required answer.

Below is the implementation of the above approach:

## C++

 `// C++ program of the above approach``#include ``#include ``#define R 3``#define C 3``using` `namespace` `std;` `// A utility function that returns``// minimum of 3 integers``int` `min(``int` `x, ``int` `y, ``int` `z)``{``    ``if` `(x < y)``        ``return` `(x < z) ? x : z;``    ``else``        ``return` `(y < z) ? y : z;``}` `// Function to find the min cost path``int` `minCost(``int` `X[R][C], ``int` `Y[R][C],``            ``int` `Z[R][C], ``int` `n)``{``    ``int` `i, j;` `    ``// 2D array to store DP states``    ``int` `dp[R][C];` `    ``dp[0][0] = 0;` `    ``// Initialize first row of dp array``    ``for` `(j = 1; j < n; j++)``        ``dp[0][j] = dp[0][j - 1] + X[0][j - 1];` `    ``// Initialize first column of dp array``    ``for` `(i = 1; i < n; i++)``        ``dp[i][0] = dp[i - 1][0] + Y[i - 1][0];` `    ``// Construct rest of the dp array``    ``for` `(i = 1; i < n; i++)``        ``for` `(j = 1; j < n; j++)` `            ``// Calculating the minimum over``            ``// the downward, right or the``            ``// diagonal movement``            ``dp[i][j]``                ``= min(``                    ``dp[i - 1][j - 1] + Z[i - 1][j - 1],``                    ``dp[i - 1][j] + Y[i - 1][j],``                    ``dp[i][j - 1] + X[i][j - 1]);` `    ``// Return answer``    ``return` `dp[n - 1][n - 1];``}` `// Driver code``int` `main()``{``    ``int` `N = 3;``    ``int` `X[R][C] = { { 1, 2, 1 },``                    ``{ 3, 4, 5 },``                    ``{ 1, 1, 1 } };``    ``int` `Y[R][C] = { { 2, 3, 4 },``                    ``{ 1, 3, 1 },``                    ``{ 2, 1, 1 } };``    ``int` `Z[R][C] = { { 1, 8, 9 },``                    ``{ 1, 4, 5 },``                    ``{ 6, 5, 4 } };` `    ``cout << minCost(X, Y, Z, 3);` `    ``return` `0;``}`

## Java

 `// Java program of the above approach` `//include ` `import` `java.util.*;``class` `GFG{``  ``static` `final` `int` `R = ``3``;``  ``static` `final` `int` `C = ``3``;` `  ``// A utility function that returns``  ``// minimum of 3 integers``  ``static` `int` `min(``int` `x, ``int` `y, ``int` `z)``  ``{``    ``if` `(x < y)``      ``return` `(x < z) ? x : z;``    ``else``      ``return` `(y < z) ? y : z;``  ``}` `  ``// Function to find the min cost path``  ``static` `int` `minCost(``int` `X[][], ``int` `Y[][],``                     ``int` `Z[][], ``int` `n)``  ``{``    ``int` `i, j;` `    ``// 2D array to store DP states``    ``int` `dp[][] = ``new` `int``[R][C];` `    ``dp[``0``][``0``] = ``0``;` `    ``// Initialize first row of dp array``    ``for` `(j = ``1``; j < n; j++)``      ``dp[``0``][j] = dp[``0``][j - ``1``] + X[``0``][j - ``1``];` `    ``// Initialize first column of dp array``    ``for` `(i = ``1``; i < n; i++)``      ``dp[i][``0``] = dp[i - ``1``][``0``] + Y[i - ``1``][``0``];` `    ``// Conrest of the dp array``    ``for` `(i = ``1``; i < n; i++)``      ``for` `(j = ``1``; j < n; j++)` `        ``// Calculating the minimum over``        ``// the downward, right or the``        ``// diagonal movement``        ``dp[i][j]``        ``= Math.min(Math.min(``          ``dp[i - ``1``][j - ``1``] + Z[i - ``1``][j - ``1``],``          ``dp[i - ``1``][j] + Y[i - ``1``][j]),``                   ``dp[i][j - ``1``] + X[i][j - ``1``]);` `    ``// Return answer``    ``return` `dp[n - ``1``][n - ``1``];``  ``}` `  ``// Driver code``  ``public` `static` `void` `main(String[] args)``  ``{``    ``int` `N = ``3``;``    ``int` `X[][] = { { ``1``, ``2``, ``1` `},``                 ``{ ``3``, ``4``, ``5` `},``                 ``{ ``1``, ``1``, ``1` `} };``    ``int` `Y[][] = { { ``2``, ``3``, ``4` `},``                 ``{ ``1``, ``3``, ``1` `},``                 ``{ ``2``, ``1``, ``1` `} };``    ``int` `Z[][] = { { ``1``, ``8``, ``9` `},``                 ``{ ``1``, ``4``, ``5` `},``                 ``{ ``6``, ``5``, ``4` `} };` `    ``System.out.print(minCost(X, Y, Z, ``3``));` `  ``}``}` `// This code is contributed by shikhasingrajput`

## Python3

 `# Python code for the above approach``R ``=` `3``C ``=` `3` `# A utility function that returns``# minimum of 3 integers``def` `min``(x, y, z):``    ``if` `(x < y):``        ``return` `x ``if` `(x < z) ``else` `z;``    ``else``:``        ``return` `y ``if` `(y < z) ``else` `z;` `# Function to find the min cost path``def` `minCost(X, Y, Z, n):``    ``i ``=` `None``    ``j ``=` `None` `    ``# 2D array to store DP states``    ``dp ``=` `[``0``] ``*` `R;` `    ``for` `i ``in` `range``(``len``(dp)):``        ``dp[i] ``=` `[``0``] ``*` `C` `    ``dp[``0``][``0``] ``=` `0``;` `    ``# Initialize first row of dp array``    ``for` `j ``in` `range``(``1``, n):``        ``dp[``0``][j] ``=` `dp[``0``][j ``-` `1``] ``+` `X[``0``][j ``-` `1``];` `    ``# Initialize first column of dp array``    ``for` `i ``in` `range``(``1``, n):``        ``dp[i][``0``] ``=` `dp[i ``-` `1``][``0``] ``+` `Y[i ``-` `1``][``0``];` `    ``# Construct rest of the dp array``    ``for` `i ``in` `range``(``1``, n):``        ``for` `j ``in` `range``(``1``, n):` `            ``# Calculating the minimum over``            ``# the downward, right or the``            ``# diagonal movement``            ``dp[i][j] ``=` `min``(``                    ``dp[i ``-` `1``][j ``-` `1``] ``+` `Z[i ``-` `1``][j ``-` `1``],``                    ``dp[i ``-` `1``][j] ``+` `Y[i ``-` `1``][j],``                    ``dp[i][j ``-` `1``] ``+` `X[i][j ``-` `1``]);` `    ``# Return answer``    ``return` `dp[n ``-` `1``][n ``-` `1``];` `# Driver code``N ``=` `3``;``X ``=` `[[``1``, ``2``, ``1``], [``3``, ``4``, ``5``], [``1``, ``1``, ``1``]];``Y ``=` `[[``2``, ``3``, ``4``], [``1``, ``3``, ``1``], [``2``, ``1``, ``1``]];``Z ``=` `[[``1``, ``8``, ``9``], [``1``, ``4``, ``5``], [``6``, ``5``, ``4``]];``print``(minCost(X, Y, Z, ``3``));` `  ``# This code is contributed by gfgking`

## C#

 `// C# program of the above approach``using` `System;``class` `GFG {` `  ``static` `int` `R = 3;``  ``static` `int` `C = 3;` `  ``// A utility function that returns``  ``// minimum of 3 integers``  ``static` `int` `min(``int` `x, ``int` `y, ``int` `z)``  ``{``    ``if` `(x < y)``      ``return` `(x < z) ? x : z;``    ``else``      ``return` `(y < z) ? y : z;``  ``}` `  ``// Function to find the min cost path``  ``static` `int` `minCost(``int` `[,]X, ``int` `[,]Y,``                     ``int` `[,]Z, ``int` `n)``  ``{``    ``int` `i, j;` `    ``// 2D array to store DP states``    ``int` `[,]dp = ``new` `int``[R, C];` `    ``dp[0, 0] = 0;` `    ``// Initialize first row of dp array``    ``for` `(j = 1; j < n; j++)``      ``dp[0, j] = dp[0, j - 1] + X[0, j - 1];` `    ``// Initialize first column of dp array``    ``for` `(i = 1; i < n; i++)``      ``dp[i, 0] = dp[i - 1, 0] + Y[i - 1, 0];` `    ``// Conrest of the dp array``    ``for` `(i = 1; i < n; i++)``      ``for` `(j = 1; j < n; j++)` `        ``// Calculating the minimum over``        ``// the downward, right or the``        ``// diagonal movement``        ``dp[i, j]``        ``= Math.Min(Math.Min(``          ``dp[i - 1, j - 1] + Z[i - 1, j - 1],``          ``dp[i - 1, j] + Y[i - 1, j]),``                   ``dp[i, j - 1] + X[i, j - 1]);` `    ``// Return answer``    ``return` `dp[n - 1, n - 1];``  ``}` `  ``// Driver code``  ``public` `static` `void` `Main()``  ``{``    ``int` `N = 3;``    ``int` `[,]X = { { 1, 2, 1 },``                ``{ 3, 4, 5 },``                ``{ 1, 1, 1 } };``    ``int` `[,]Y = { { 2, 3, 4 },``                ``{ 1, 3, 1 },``                ``{ 2, 1, 1 } };``    ``int` `[,]Z = { { 1, 8, 9 },``                ``{ 1, 4, 5 },``                ``{ 6, 5, 4 } };` `    ``Console.Write(minCost(X, Y, Z, 3));` `  ``}``}` `// This code is contributed by Samim Hossain Mondal.`

## Javascript

 ``

Output

`4`

Time Complexity: O(N2)
Auxiliary Space: O(N2)

Memoised DP Approach:

The recurrence relation is the same as of above.

minCost(i, j) = min ( minCost(i, j – 1) + X[i][j – 1],
minCost(i – 1, j) + Y[i – 1][j],
minCost(i – 1, j – 1) + Z[i – 1][j – 1])

But instead of having bottom up approach we will be using top-down approach to solve the problem.

Following are steps to be followed to implement the approach:

1.    Define the dimensions of the matrices X, Y, and Z and the memoization table dp as R x C.
2.    Define a function min to return the minimum of three integers.
3.    Define a recursive function memoizedDP that takes X, Y, Z, dp, i, j as parameters:
a. Base case: if i and j are both zero, return 0.
b. If dp[i][j] is not -1, then return dp[i][j].
c. Define a variable ans to store the minimum cost required to reach the bottom right from (i, j).
d. Check if we can move to the left: if j > 0, recursively call memoizedDP with parameters X, Y, Z, dp, i, j – 1 and add X[i]             [j – 1] to the result.
e. Check if we can move to the top: if i > 0, recursively call memoizedDP with parameters X, Y, Z, dp, i – 1, j and add Y[i               – 1][j] to the result.
f. Check if we can move diagonally as well: if i > 0 and j > 0, recursively call memoizedDP with parameters X, Y, Z, dp, i –            1, j – 1 and add Z[i – 1][j – 1] to the result.
g. Save the computed value to dp[i][j] and return it.
4.    Define a function minCost that takes X, Y, Z, and n as parameters:
a. Declare a memoization table dp and initialize all its elements to -1.
b. Return the result of calling memoizedDP with parameters X, Y, Z, dp, n – 1, n – 1.
5.    In the main function:
a. Define the matrices X, Y, and Z with the given values and dimension N.
b. Call the minCost function with X, Y, Z, and N as parameters and output the result.

Below is the implementation of the approach:

## C++

 `#include ``#define R 3``#define C 3``using` `namespace` `std;` `// A utility function that returns``// minimum of 3 integers``int` `min(``int` `x, ``int` `y, ``int` `z)``{``    ``if` `(x < y)``        ``return` `(x < z) ? x : z;``    ``else``        ``return` `(y < z) ? y : z;``}` `// Memoization function``int` `memoizedDP(``int` `X[][C], ``int` `Y[][C], ``int` `Z[][C],``               ``int` `dp[][C], ``int` `i, ``int` `j)``{``    ``// Base case``    ``if` `(i == 0 && j == 0)``        ``return` `dp[i][j] = 0;` `    ``// Check if the value is already computed``    ``if` `(dp[i][j] != -1)``        ``return` `dp[i][j];` `    ``int` `ans = INT_MAX;` `    ``// If we can move to the left``    ``if` `(j > 0)``        ``ans = min(ans, memoizedDP(X, Y, Z, dp, i, j - 1) + X[i][j - 1]);` `    ``// If we can move to the top``    ``if` `(i > 0)``        ``ans = min(ans, memoizedDP(X, Y, Z, dp, i - 1, j) + Y[i - 1][j]);` `    ``// If we can move diagonally as well``    ``if` `(i > 0 && j > 0)``        ``ans = min(ans, memoizedDP(X, Y, Z, dp, i - 1, j - 1) + Z[i - 1][j - 1]);` `    ``// Save the computed value and return it``    ``return` `dp[i][j] = ans;``}` `// Function to find the min cost path``int` `minCost(``int` `X[][C], ``int` `Y[][C], ``int` `Z[][C], ``int` `n)``{``    ``int` `dp[R][C];``    ``memset``(dp, -1, ``sizeof``(dp));` `    ``return` `memoizedDP(X, Y, Z, dp, n - 1, n - 1);``}` `// Driver code``int` `main()``{``    ``int` `N = 3;``    ``int` `X[R][C] = {{1, 2, 1},``                   ``{3, 4, 5},``                   ``{1, 1, 1}};``    ``int` `Y[R][C] = {{2, 3, 4},``                   ``{1, 3, 1},``                   ``{2, 1, 1}};``    ``int` `Z[R][C] = {{1, 8, 9},``                   ``{1, 4, 5},``                   ``{6, 5, 4}};` `    ``cout << minCost(X, Y, Z, 3);` `    ``return` `0;``}` `// This code is contributed by Chandramani Kumar`

Output

`4`

Time Complexity: O(N2) where N is size of the input cost matrices  X, Y and Z.
Space Complexity: O(N2) as 2D dp array has been created of size N*N where N is size of the input cost matrices  X, Y and Z.