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: 0
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: 2
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++ 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 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 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# 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 |
<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> |
0