给定两个N行M列的二维数组b[][]和c[][] 。的任务是,以尽量减少B的[i] [j] S之和的绝对差和c的总和[i] [j]沿着从(0,0)到(N的路径S – 1,M – 1 ) 。
例子:
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
方法:答案与决定b[i][j]和c[i][j]的顺序和路径无关。因此,让我们考虑一个 bollean 表,如果(i, j)可以达到k 的最小差异,则dp[i][j][k]将为真。
如果它为真,那么对于单元格(i + 1, j),它要么是k + |b i+1, j – c i+1, j |或|k – |b i+1, j – c i+1, j || . square (i, j + 1)也是如此。因此,可以按i和j的递增顺序填充该表。
下面是上述方法的实现:
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 code
int 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 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
0
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。