Given two arrays A[] and B[] consisting of M and N integers respectively, and an integer C, the task is to find the minimum cost required to make the sequence A exactly the same as B(consists of distinct elements only) by performing the following operations on array A[]:
- Remove any element from the array with cost 0.
- Insert a new element anywhere in the array with cost C.
Examples:
Input: A[] = {1, 6, 3, 5, 10}, B[] = {3, 1, 5}, C = 2
Output: 2
Explanation:
Removing elements 1, 6, and 10 from the array costs 0. The array A[] becomes {3, 5}.
Add 1 in between 3 and 5, then the array arr[] becomes {3, 1, 5} which is the same as the array B[].
The cost of above operation is 2.
Input: A[] = {10, 5, 2, 4, 10, 5}, B[] = {5, 1, 2, 10, 4}, C = 3
Output: 6
Explanation:
Removing elements 10, 10, and 5 from the array costs 0. The array A[] becomes {5, 2, 4}.
Add element 1 and 10 in the array as {5, 1, 2, 10, 4} which is the same as the array B[].
The cost of above operation is 3*2 = 6.
Naive Approach: The simplest approach is to erase all the elements from array A[] which are not present in array B[] by using two for loops. After that generate all permutations of the remaining element in the array and for each sequence check for the minimum cost such that the array A[] is the same as the array B[]. Print the minimum cost of the same.
Time Complexity: O(N!*N*M), where N is the size of the array A[] and M is the size of the array B[].
Auxiliary Space: O(1)
Efficient Approach: To optimize the above approach, the idea is to first find the length of the longest common subsequence of array A[] and B[] and subtract it from the size of array B[], which gives the number of elements to be added in array A[]. And add amount C into the cost for every new element added. Therefore, the total cost is given by:
Cost = C*(N – LCS(A, B))
where,
LCS is the longest common subsequence of the arrays A[] and B[],
N is the length of the array A[], and
C is the cost of adding each element in the array B[].
Follow the steps below to solve the problem:
- Create a new array say index[] and initialize it with -1 and an array nums[].
- Map each element of the array B[] to its corresponding index in the array index[].
- Traverse the given array A[] and insert the values with its mapped values i.e., index number into the array nums[] array and if the index number is not -1.
- Now find the Longest Increasing Subsequence of the array nums[] to obtain the length of the longest common subsequence of the two given arrays.
- After finding the LCS in the above steps, find the value of cost using the formula discussed above.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int findLCS( int * nums, int N)
{
int k = 0;
for ( int i = 0; i < N; i++) {
int pos = lower_bound(nums, nums + k,
nums[i])
- nums;
nums[pos] = nums[i];
if (k == pos) {
k = pos + 1;
}
}
return k;
}
int minimumCost( int * A, int * B, int M,
int N, int C)
{
int nums[1000000];
int index[1000000];
memset (index, -1, sizeof (index));
for ( int i = 0; i < N; i++) {
index[B[i]] = i;
}
int k = 0;
for ( int i = 0; i < M; i++) {
if (index[A[i]] != -1) {
nums[k++] = index[A[i]];
}
}
int lcs_length = findLCS(nums, k);
int elements_to_be_added
= N - lcs_length;
int min_cost
= elements_to_be_added * C;
cout << min_cost;
}
int main()
{
int A[] = { 1, 6, 3, 5, 10 };
int B[] = { 3, 1, 5 };
int C = 2;
int M = sizeof (A) / sizeof (A[0]);
int N = sizeof (B) / sizeof (B[0]);
minimumCost(A, B, M, N, C);
return 0;
}
|
Java
import java.io.*;
class GFG{
static int LowerBound( int a[], int k,
int x)
{
int l = - 1 ;
int r = k;
while (l + 1 < r)
{
int m = (l + r) >>> 1 ;
if (a[m] >= x)
{
r = m;
}
else
{
l = m;
}
}
return r;
}
static int findLCS( int [] nums, int N)
{
int k = 0 ;
for ( int i = 0 ; i < N; i++)
{
int pos = LowerBound(nums, k,
nums[i]);
nums[pos] = nums[i];
if (k == pos)
{
k = pos + 1 ;
}
}
return k;
}
static int minimumCost( int [] A, int [] B,
int M, int N, int C)
{
int [] nums = new int [ 100000 ];
int [] index = new int [ 100000 ];
for ( int i = 0 ; i < 100000 ; i++)
index[i] = - 1 ;
for ( int i = 0 ; i < N; i++)
{
index[B[i]] = i;
}
int k = 0 ;
for ( int i = 0 ; i < M; i++)
{
if (index[A[i]] != - 1 )
{
nums[k++] = index[A[i]];
}
}
int lcs_length = findLCS(nums, k);
int elements_to_be_added = N - lcs_length;
int min_cost = elements_to_be_added * C;
System.out.println( min_cost);
return 0 ;
}
public static void main(String[] args)
{
int [] A = { 1 , 6 , 3 , 5 , 10 };
int [] B = { 3 , 1 , 5 };
int C = 2 ;
int M = A.length;
int N = B.length;
minimumCost(A, B, M, N, C);
}
}
|
Python3
def LowerBound(a, k, x):
l = - 1
r = k
while (l + 1 < r):
m = (l + r) >> 1
if (a[m] > = x):
r = m
else :
l = m
return r
def findLCS(nums, N):
k = 0
for i in range (N):
pos = LowerBound(nums, k, nums[i])
nums[pos] = nums[i]
if (k = = pos):
k = pos + 1
return k
def minimumCost(A, B, M, N, C):
nums = [ 0 ] * 100000
index = [ - 1 ] * 100000
for i in range (N):
index[B[i]] = i
k = 0
for i in range (M):
if (index[A[i]] ! = - 1 ):
k + = 1
nums[k] = index[A[i]]
lcs_length = findLCS(nums, k)
elements_to_be_added = N - lcs_length
min_cost = elements_to_be_added * C
print ( min_cost)
A = [ 1 , 6 , 3 , 5 , 10 ]
B = [ 3 , 1 , 5 ]
C = 2
M = len (A)
N = len (B)
minimumCost(A, B, M, N, C)
|
C#
using System;
class GFG{
static int LowerBound( int [] a, int k,
int x)
{
int l = -1;
int r = k;
while (l + 1 < r)
{
int m = (l + r) >> 1;
if (a[m] >= x)
{
r = m;
}
else
{
l = m;
}
}
return r;
}
static int findLCS( int [] nums, int N)
{
int k = 0;
for ( int i = 0; i < N; i++)
{
int pos = LowerBound(nums, k,
nums[i]);
nums[pos] = nums[i];
if (k == pos)
{
k = pos + 1;
}
}
return k;
}
static int minimumCost( int [] A, int [] B,
int M, int N, int C)
{
int [] nums = new int [100000];
int [] index = new int [100000];
for ( int i = 0; i < 100000; i++)
index[i] = -1;
for ( int i = 0; i < N; i++)
{
index[B[i]] = i;
}
int k = 0;
for ( int i = 0; i < M; i++)
{
if (index[A[i]] != -1)
{
nums[k++] = index[A[i]];
}
}
int lcs_length = findLCS(nums, k);
int elements_to_be_added = N - lcs_length;
int min_cost = elements_to_be_added * C;
Console.WriteLine(min_cost);
return 0;
}
public static void Main()
{
int [] A = { 1, 6, 3, 5, 10 };
int [] B = { 3, 1, 5 };
int C = 2;
int M = A.Length;
int N = B.Length;
minimumCost(A, B, M, N, C);
}
}
|
Javascript
<script>
function LowerBound(a , k , x) {
var l = -1;
var r = k;
while (l + 1 < r) {
var m = (l + r) >>> 1;
if (a[m] >= x) {
r = m;
} else {
l = m;
}
}
return r;
}
function findLCS(nums , N) {
var k = 0;
for (i = 0; i < N; i++) {
var pos = LowerBound(nums, k, nums[i]);
nums[pos] = nums[i];
if (k == pos) {
k = pos + 1;
}
}
return k;
}
function minimumCost(A, B , M , N , C) {
var nums = Array(100000).fill(0);
var index = Array(100000).fill(0);
for (i = 0; i < 100000; i++)
index[i] = -1;
for (i = 0; i < N; i++) {
index[B[i]] = i;
}
var k = 0;
for (i = 0; i < M; i++) {
if (index[A[i]] != -1) {
nums[k++] = index[A[i]];
}
}
var lcs_length = findLCS(nums, k);
var elements_to_be_added = N - lcs_length;
var min_cost = elements_to_be_added * C;
document.write(min_cost);
return 0;
}
var A = [ 1, 6, 3, 5, 10 ];
var B = [ 3, 1, 5 ];
var C = 2;
var M = A.length;
var N = B.length;
minimumCost(A, B, M, N, C);
</script>
|
Time Complexity: O(N * Log N)
Auxiliary Space: O(N)