Open In App

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

Improve
Improve
Like Article
Like
Save
Share
Report

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 <bits/stdc++.h>
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<vector<int> > b,
                  vector<vector<int> > 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 code
int main()
{
    n = 2, m = 2;
 
    vector<vector<int> > b = { { 1, 4 }, { 2, 4 } };
 
    vector<vector<int> > 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 approach
class 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 approach
import numpy as np
import 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 code
if __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 approach
using 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




<script>
 
    // JavaScript implementation of the approach
     
    let MAXI = 50 ;
       
    let dp = new Array(MAXI);
    let n, m;
    let INT_MAX = Number.MAX_VALUE;
       
    // Function to return the minimum difference
    // path from (0, 0) to (N - 1, M - 1)
    function minDifference(x, y, k, b, c)
    {
       
        // Terminating case
        if (x >= n || y >= m)
            return INT_MAX;
       
        // Base case
        if (x == n - 1 && y == m - 1)
        {
            let diff = b[x][y] - c[x][y];
       
            return Math.min(Math.abs(k - diff),
                            Math.abs(k + diff));
        }
       
        let ans = dp[x][y][k];
       
        // If it is already visited
        if (ans != -1)
            return ans;
       
        ans = INT_MAX;
       
        let 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;
    }
     
    n = 2; m = 2;
       
    let b = [ [ 1, 4 ], [ 2, 4 ] ];
 
    let c = [ [ 3, 2 ], [ 3, 1 ] ];
 
    for(let i = 0; i < MAXI; i++)
    {
      dp[i] = new Array(MAXI);
      for(let j = 0; j < MAXI; j++)
      {
          dp[i][j] = new Array(MAXI * MAXI);
        for(let k = 0; k < MAXI * MAXI; k++)
        {
          dp[i][j][k] = -1;
        }
      }
    }
 
    // Function call
    document.write(minDifference(0, 0, 0, b, c));
     
</script>


Output: 

0

 



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