Open In App

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

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

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 <bits/stdc++.h>
#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


Java




// Java program of the above approach
 
import java.util.*;
public class GFG {
    static final int R = 3;
    static final int C = 3;
 
    // A utility function that returns
    // minimum of integers
    static int min(int x, int y) { return x < y ? x : y; }
 
    // Recursive utility function
    static int minCostUtil(int[][] X, int[][] Y, int[][] Z,
                           int i, int j)
    {
        // Base case
        if (i == 0 && j == 0)
            return 0;
 
        int ans = Integer.MAX_VALUE;
 
        // 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
    static int minCost(int[][] X, int[][] Y, int[][] Z,
                       int n)
    {
        return minCostUtil(X, Y, Z, 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.println(minCost(X, Y, Z, 3));
    }
}


Python3




# A utility function that returns
# minimum of integers
def min_val(x, y):
    return x if x < y else y
 
# Recursive utility function
def min_cost_util(X, Y, Z, i, j):
    # Base case
    if i == 0 and j == 0:
        return 0
 
    ans = float('inf')
 
    # If we can move to the left
    if j > 0:
        ans = min_val(ans, min_cost_util(X, Y, Z, i, j - 1) + X[i][j - 1])
 
    # If we can move to the top
    if i > 0:
        ans = min_val(ans, min_cost_util(X, Y, Z, i - 1, j) + Y[i - 1][j])
 
    # If we can move diagonally as well
    if i > 0 and j > 0:
        ans = min_val(ans, min_cost_util(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
def min_cost(X, Y, Z, n):
    return min_cost_util(X, Y, Z, n - 1, n - 1)
 
# Driver code
if __name__ == "__main__":
    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(min_cost(X, Y, Z, 3))


C#




using System;
 
class Program
{
    const int R = 3;
    const int C = 3;
 
    // Recursive utility function
    static int MinCostUtil(int[,] X, int[,] Y, int[,] Z, int i, int j)
    {
        // Base case
        if (i == 0 && j == 0)
            return 0;
 
        int ans = int.MaxValue;
 
        // If we can move to the left
        if (j > 0)
            ans = Math.Min(ans, MinCostUtil(X, Y, Z, i, j - 1) + X[i, j - 1]);
 
        // If we can move to the top
        if (i > 0)
            ans = Math.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 = Math.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
    static int MinCost(int[,] X, int[,] Y, int[,] Z, int n)
    {
        return MinCostUtil(X, Y, Z, n - 1, n - 1);
    }
 
    // Driver code
    static void Main()
    {
        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.WriteLine(MinCost(X, Y, Z, 3));
    }
}


Javascript




// Javascript program of the above approach
 
    // A utility function that returns
    // minimum of integers
function minCost(X, Y, Z, n) {
    const min = (x, y) => x < y ? x : y;
 
// Recursive utility function
    function minCostUtil(i, j) {
        if (i === 0 && j === 0)
            return 0;
 
        let ans = Number.MAX_SAFE_INTEGER;
 
        if (j > 0)
            ans = min(ans, minCostUtil(i, j - 1) + X[i][j - 1]);
 
        if (i > 0)
            ans = min(ans, minCostUtil(i - 1, j) + Y[i - 1][j]);
 
        if (i > 0 && j > 0)
            ans = min(ans, minCostUtil(i - 1, j - 1) + Z[i - 1][j - 1]);
 
        return ans;
    }
 
    return minCostUtil(n - 1, n - 1);
}
 
    // Driver code
const N = 3;
const X = [
    [1, 2, 1],
    [3, 4, 5],
    [1, 1, 1]
];
const Y = [
    [2, 3, 4],
    [1, 3, 1],
    [2, 1, 1]
];
const Z = [
    [1, 8, 9],
    [1, 4, 5],
    [6, 5, 4]
];
 
console.log(minCost(X, Y, Z, N));


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 <bits/stdc++.h>
#include <limits.h>
#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 <limits.h>
 
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




<script>
        // JavaScript code for the above approach
        let R = 3
        let C = 3
 
        // A utility function that returns
        // minimum of 3 integers
        function min(x, y, z) {
            if (x < y)
                return (x < z) ? x : z;
            else
                return (y < z) ? y : z;
        }
 
        // Function to find the min cost path
        function minCost(X, Y,
            Z, n) {
            let i, j;
 
            // 2D array to store DP states
            let dp = new Array(R);
 
            [C];
 
            for (let i = 0; i < dp.length; i++) {
                dp[i] = new Array(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]
                        = 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
        let N = 3;
        let X = [[1, 2, 1],
        [3, 4, 5],
        [1, 1, 1]
        ];
        let Y = [[2, 3, 4],
        [1, 3, 1],
        [2, 1, 1]];
        let Z = [[1, 8, 9],
        [1, 4, 5],
        [6, 5, 4]];
 
        document.write(minCost(X, Y, Z, 3));
 
  // This code is contributed by Potta Lokesh
    </script>


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 <bits/stdc++.h>
#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


Java




public class Main {
    static final int R = 3;
    static final int C = 3;
 
    // A utility function that returns the minimum of two integers
    static int min(int x, int y) {
        return x < y ? x : y;
    }
 
    // Memoization function
    static int memoizedDP(int[][] X, int[][] Y, int[][] Z, int[][] dp, 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 = Integer.MAX_VALUE;
 
        // 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
    static int minCost(int[][] X, int[][] Y, int[][] Z, int n) {
        int[][] dp = new int[R][C];
        for (int i = 0; i < R; i++) {
            for (int j = 0; j < C; j++) {
                dp[i][j] = -1;
            }
        }
        return memoizedDP(X, Y, Z, dp, n - 1, n - 1);
    }
 
    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.println(minCost(X, Y, Z, N));
    }
}


Python




class Main:
    R = 3
    C = 3
    # A utility function that returns the minimum of the two integers
    def min(self, x, y):
        return x if x < y else y
    # Memoization function
    def memoized_dp(self, X, Y, Z, dp, i, j):
        # Base case
        if i == 0 and j == 0:
            return 0
        # Check if the value is already computed
        if dp[i][j] != -1:
            return dp[i][j]
        ans = float('inf')
        # If we can move to left
        if j > 0:
            ans = self.min(ans, self.memoized_dp(X, Y, Z, dp, i, j - 1) + X[i][j - 1])
        # If we can move to the top
        if i > 0:
            ans = self.min(ans, self.memoized_dp(X, Y, Z, dp, i - 1, j) + Y[i - 1][j])
        # If we can move diagonally as well
        if i > 0 and j > 0:
            ans = self.min(ans, self.memoized_dp(X, Y, Z, dp, i - 1, j - 1) + Z[i - 1][j - 1])
        dp[i][j] = ans
        return ans
    # Function to find the min cost path
    def min_cost(self, X, Y, Z, n):
        dp = [[-1 for _ in range(self.C)] for _ in range(self.R)]
        return self.memoized_dp(X, Y, Z, dp, n - 1, n - 1)
    def GFG(self):
        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(self.min_cost(X, Y, Z, N))
 
if __name__ == "__main__":
    main_obj = Main()
    main_obj.GFG()


C#




using System;
 
class Solution
{
    // Memoization function
    static int MemoizedDP(int[,] X, int[,] Y, int[,] Z, int[,] dp, 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.MaxValue;
 
        // If we can move to the left
        if (j > 0)
            ans = Math.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 = Math.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 = Math.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
    static int MinCost(int[,] X, int[,] Y, int[,] Z, int n)
    {
        int[,] dp = new int[n, n];
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                dp[i, j] = -1;
            }
        }
 
        return MemoizedDP(X, Y, Z, dp, n - 1, n - 1);
    }
 
    // Driver code
    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.WriteLine(MinCost(X, Y, Z, N));
    }
}


Javascript




//Javascript Code for the given approach
const R = 3;
const C = 3;
// A utility function that returns
// minimum of integers
function min(x, y) {
  return x < y ? x : y;
}
 
// Memoization function
function memoizedDP(X, Y, Z, dp, i, 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];
 
  let ans = Infinity;
 
  // 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
function minCost(X, Y, Z, n) {
  const dp = new Array(R).fill(null).map(() => new Array(C).fill(-1));
  return memoizedDP(X, Y, Z, dp, n - 1, n - 1);
}
 
// Driver code
const N = 3;
const X = [
  [1, 2, 1],
  [3, 4, 5],
  [1, 1, 1],
];
const Y = [
  [2, 3, 4],
  [1, 3, 1],
  [2, 1, 1],
];
const Z = [
  [1, 8, 9],
  [1, 4, 5],
  [6, 5, 4],
];
 
console.log(minCost(X, Y, Z, N));


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.



Last Updated : 28 Dec, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads