Find the minimum difference path from (0, 0) to (N-1, M-1)

• Difficulty Level : Hard
• Last Updated : 23 Dec, 2021

Given two 2D arrays b[][] and c[][] of N rows and M columns. The task is to minimise the absolute difference of the sum of b[i][j]s and the sum of c[i][j]s along the path from (0, 0) to (N – 1, M – 1).
Examples:

Input: b[][] = {{1, 4}, {2, 4}}, c[][] = {{3, 2}, {3, 1}}
Output:
Choose path (0, 0) -> (1, 0) -> (1, 1)
sum of b[i][j]s are = 1 + 2 + 4 = 7
sum of c[i][j]s are = 3 + 3 + 1 = 7
absolute difference is zero
Input: b[][] = {{1, 10, 50}, {50, 10, 1}}, c[][] = {{1, 2, 3}, {4, 5, 6}}
Output:

Approach: The answer is independent from the order of deciding b[i][j] and c[i][j] and the path. So let’s consider a boolean table such that dp[i][j][k] will be true if (i, j) can be reached with minimum difference of k
If it is true then for the cell (i + 1, j) it is either k + |bi+1, j – ci+1, j| or |k – |bi+1, j – ci+1, j||. The same is true for square (i, j + 1). Therefore, the table can be filled in the increasing order of i and j.
Below is the implementation of the above approach:

C++

 // C++ implementation of the approach#include using namespace std; #define MAXI 50 int dp[MAXI][MAXI][MAXI * MAXI];int n, m; // Function to return the minimum difference// path from (0, 0) to (N - 1, M - 1)int minDifference(int x, int y, int k,                  vector > b,                  vector > c){     // Terminating case    if (x >= n or y >= m)        return INT_MAX;     // Base case    if (x == n - 1 and y == m - 1) {        int diff = b[x][y] - c[x][y];         return min(abs(k - diff), abs(k + diff));    }     int& ans = dp[x][y][k];     // If it is already visited    if (ans != -1)        return ans;     ans = INT_MAX;     int diff = b[x][y] - c[x][y];     // Recursive calls    ans = min(ans, minDifference(x + 1, y,                                 abs(k + diff), b, c));    ans = min(ans, minDifference(x, y + 1,                                 abs(k + diff), b, c));     ans = min(ans, minDifference(x + 1, y,                                 abs(k - diff), b, c));    ans = min(ans, minDifference(x, y + 1,                                 abs(k - diff), b, c));     // Return the value    return ans;} // Driver codeint main(){    n = 2, m = 2;     vector > b = { { 1, 4 }, { 2, 4 } };     vector > c = { { 3, 2 }, { 3, 1 } };     memset(dp, -1, sizeof(dp));     // Function call    cout << minDifference(0, 0, 0, b, c);     return 0;}

Java

 // Java implementation of the approachclass GFG{    final static int MAXI = 50 ;         static int dp[][][] = new int[MAXI][MAXI][MAXI * MAXI];    static int n, m;    final static int INT_MAX = Integer.MAX_VALUE;         // Function to return the minimum difference    // path from (0, 0) to (N - 1, M - 1)    static int minDifference(int x, int y, int k,                             int b[][], int c[][])    {             // Terminating case        if (x >= n || y >= m)            return INT_MAX;             // Base case        if (x == n - 1 && y == m - 1)        {            int diff = b[x][y] - c[x][y];                 return Math.min(Math.abs(k - diff),                            Math.abs(k + diff));        }             int ans = dp[x][y][k];             // If it is already visited        if (ans != -1)            return ans;             ans = INT_MAX;             int diff = b[x][y] - c[x][y];             // Recursive calls        ans = Math.min(ans, minDifference(x + 1, y,              Math.abs(k + diff), b, c));                 ans = Math.min(ans, minDifference(x, y + 1,              Math.abs(k + diff), b, c));             ans = Math.min(ans, minDifference(x + 1, y,              Math.abs(k - diff), b, c));        ans = Math.min(ans, minDifference(x, y + 1,              Math.abs(k - diff), b, c));             // Return the value        return ans;    }         // Driver code    public static void main (String[] args)    {        n = 2; m = 2;             int b[][] = { { 1, 4 }, { 2, 4 } };             int c[][] = { { 3, 2 }, { 3, 1 } };             for(int i = 0; i < MAXI; i++)        {            for(int j = 0; j < MAXI; j++)            {                for(int k = 0; k < MAXI * MAXI; k++)                {                    dp[i][j][k] = -1;                }            }        }             // Function call        System.out.println(minDifference(0, 0, 0, b, c));    }} // This code is contributed by AnkitRai01

Python3

 # Python3 implementation of the approachimport numpy as npimport sys MAXI = 50 INT_MAX = sys.maxsize dp = np.ones((MAXI, MAXI, MAXI * MAXI));dp *= -1 # Function to return the minimum difference# path from (0, 0) to (N - 1, M - 1)def minDifference(x, y, k, b, c) :     # Terminating case    if (x >= n or y >= m) :        return INT_MAX;     # Base case    if (x == n - 1 and y == m - 1) :        diff = b[x][y] - c[x][y];         return min(abs(k - diff), abs(k + diff));     ans = dp[x][y][k];     # If it is already visited    if (ans != -1) :        return ans;     ans = INT_MAX;     diff = b[x][y] - c[x][y];     # Recursive calls    ans = min(ans, minDifference(x + 1, y,                      abs(k + diff), b, c));         ans = min(ans, minDifference(x, y + 1,                    abs(k + diff), b, c));     ans = min(ans, minDifference(x + 1, y,                    abs(k - diff), b, c));         ans = min(ans, minDifference(x, y + 1,                    abs(k - diff), b, c));     # Return the value    return ans; # Driver codeif __name__ == "__main__" :     n = 2; m = 2; b = [ [ 1, 4 ], [ 2, 4 ] ];     c = [ [ 3, 2 ], [ 3, 1 ] ];     # Function call    print(minDifference(0, 0, 0, b, c)); # This code is contributed by AnkitRai01

C#

 // C# implementation of the approachusing System; class GFG{    static int MAXI = 50 ;         static int [,,]dp = new int[MAXI, MAXI,                                MAXI * MAXI];    static int n, m;    static int INT_MAX = int.MaxValue;         // Function to return the minimum difference    // path from (0, 0) to (N - 1, M - 1)    static int minDifference(int x, int y, int k,                             int [,]b, int [,]c)    {        int diff = 0;             // Terminating case        if (x >= n || y >= m)            return INT_MAX;             // Base case        if (x == n - 1 && y == m - 1)        {            diff = b[x, y] - c[x, y];                 return Math.Min(Math.Abs(k - diff),                            Math.Abs(k + diff));        }             int ans = dp[x, y, k];             // If it is already visited        if (ans != -1)            return ans;             ans = INT_MAX;             diff = b[x, y] - c[x, y];             // Recursive calls        ans = Math.Min(ans, minDifference(x + 1, y,              Math.Abs(k + diff), b, c));                 ans = Math.Min(ans, minDifference(x, y + 1,              Math.Abs(k + diff), b, c));             ans = Math.Min(ans, minDifference(x + 1, y,              Math.Abs(k - diff), b, c));                 ans = Math.Min(ans, minDifference(x, y + 1,              Math.Abs(k - diff), b, c));             // Return the value        return ans;    }         // Driver code    public static void Main ()    {        n = 2; m = 2;             int [,]b = { { 1, 4 }, { 2, 4 } };             int [,]c = { { 3, 2 }, { 3, 1 } };             for(int i = 0; i < MAXI; i++)        {            for(int j = 0; j < MAXI; j++)            {                for(int k = 0; k < MAXI * MAXI; k++)                {                    dp[i, j, k] = -1;                }            }        }             // Function call        Console.WriteLine(minDifference(0, 0, 0, b, c));    }} // This code is contributed by AnkitRai01

Javascript


Output:
0

My Personal Notes arrow_drop_up