给定两个分别由N和M 个整数组成的数组A[]和B[]以及一个整数C ,任务是找到使序列A与B完全相同(仅由不同元素组成)所需的最小成本对数组A[]执行以下操作:
- 从数组中删除任何成本为0 的元素。
- 在数组中的任意位置插入一个新元素,成本为C 。
例子:
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.
朴素的方法:最简单的方法是使用两个 for 循环擦除数组A[]中不存在于数组B[] 中的所有元素。之后生成数组中剩余元素的所有排列,并为每个序列检查最小成本,使得数组A[]与数组B[] 相同。打印相同的最低成本。
时间复杂度: O(N!*N*M),其中 N 是数组 A[] 的大小,M 是数组 B[] 的大小。
辅助空间: O(1)
高效方法:为了优化上述方法,其思想是首先找到数组A[]和B[]的最长公共子序列的长度,并从数组B[]的大小中减去它,得到元素数添加到数组A[] 中。并将数量C添加到每个添加新元素的成本中。因此,总成本由下式给出:
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[].
请按照以下步骤解决问题:
- 创建一个新数组index[]并使用-1和数组nums[]对其进行初始化。
- 将数组B[] 的每个元素映射到数组index[]中的对应索引。
- 遍历给定的数组A[]并插入值及其映射值,即索引号到数组nums[]数组中,如果索引号不是-1 。
- 现在找到数组nums[]的最长递增子序列,以获得两个给定数组的最长公共子序列的长度。
- 在上述步骤中找到 LCS 后,使用上面讨论的公式找到成本值。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find length of the
// longest common subsequence
int findLCS(int* nums, int N)
{
int k = 0;
for (int i = 0; i < N; i++) {
// Find position where element
// is to be inserted
int pos = lower_bound(nums, nums + k,
nums[i])
- nums;
nums[pos] = nums[i];
if (k == pos) {
k = pos + 1;
}
}
// Return the length of LCS
return k;
}
// Function to find the minimum cost
// required to convert the sequence A
// exactly same as B
int minimumCost(int* A, int* B, int M,
int N, int C)
{
// Auxiliary array
int nums[1000000];
// Stores positions of elements of A[]
int index[1000000];
// Initialize index array with -1
memset(index, -1, sizeof(index));
for (int i = 0; i < N; i++) {
// Update the index array with
// index of corresponding
// elements of B
index[B[i]] = i;
}
int k = 0;
for (int i = 0; i < M; i++) {
// Place only A's array values
// with its mapped values
// into nums array
if (index[A[i]] != -1) {
nums[k++] = index[A[i]];
}
}
// Find LCS
int lcs_length = findLCS(nums, k);
// No of elements to be added
// in array A[]
int elements_to_be_added
= N - lcs_length;
// Stores minimum cost
int min_cost
= elements_to_be_added * C;
// Print the minimum cost
cout << min_cost;
}
// Driver Code
int main()
{
// Given array A[]
int A[] = { 1, 6, 3, 5, 10 };
int B[] = { 3, 1, 5 };
// Given C
int C = 2;
// Size of arr A
int M = sizeof(A) / sizeof(A[0]);
// Size of arr B
int N = sizeof(B) / sizeof(B[0]);
// Function Call
minimumCost(A, B, M, N, C);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
class GFG{
// Function to find lower_bound
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;
}
// Function to find length of the
// longest common subsequence
static int findLCS(int[] nums, int N)
{
int k = 0;
for(int i = 0; i < N; i++)
{
// Find position where element
// is to be inserted
int pos = LowerBound(nums, k,
nums[i]);
nums[pos] = nums[i];
if (k == pos)
{
k = pos + 1;
}
}
// Return the length of LCS
return k;
}
// Function to find the minimum cost
// required to convert the sequence A
// exactly same as B
static int minimumCost(int[] A, int[] B,
int M, int N, int C)
{
// Auxiliary array
int[] nums = new int[100000];
// Stores positions of elements of A[]
int[] index = new int[100000];
// Initialize index array with -1
for(int i = 0; i < 100000; i++)
index[i] = -1;
for(int i = 0; i < N; i++)
{
// Update the index array with
// index of corresponding
// elements of B
index[B[i]] = i;
}
int k = 0;
for(int i = 0; i < M; i++)
{
// Place only A's array values
// with its mapped values
// into nums array
if (index[A[i]] != -1)
{
nums[k++] = index[A[i]];
}
}
// Find LCS
int lcs_length = findLCS(nums, k);
// No of elements to be added
// in array A[]
int elements_to_be_added = N - lcs_length;
// Stores minimum cost
int min_cost = elements_to_be_added * C;
// Print the minimum cost
System.out.println( min_cost);
return 0;
}
// Driver code
public static void main(String[] args)
{
// Given array A[]
int[] A = { 1, 6, 3, 5, 10 };
int[] B = { 3, 1, 5 };
// Given C
int C = 2;
// Size of arr A
int M = A.length;
// Size of arr B
int N = B.length;
// Function call
minimumCost(A, B, M, N, C);
}
}
// This code is contributed by sallagondaavinashreddy7
Python3
# Python3 program for the above approach
# Function to find lower_bound
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
# Function to find length of the
# longest common subsequence
def findLCS(nums, N):
k = 0
for i in range(N):
# Find position where element
# is to be inserted
pos = LowerBound(nums, k, nums[i])
nums[pos] = nums[i]
if (k == pos):
k = pos + 1
# Return the length of LCS
return k
# Function to find the minimum cost
# required to convert the sequence A
# exactly same as B
def minimumCost(A, B, M, N, C):
# Auxiliary array
nums = [0] * 100000
# Stores positions of elements of A[]
# Initialize index array with -1
index = [-1] * 100000
for i in range(N):
# Update the index array with
# index of corresponding
# elements of B
index[B[i]] = i
k = 0
for i in range(M):
# Place only A's array values
# with its mapped values
# into nums array
if (index[A[i]] != -1):
k += 1
nums[k] = index[A[i]]
# Find LCS
lcs_length = findLCS(nums, k)
# No of elements to be added
# in array A[]
elements_to_be_added = N - lcs_length
# Stores minimum cost
min_cost = elements_to_be_added * C
# Print the minimum cost
print( min_cost)
# Driver Code
# Given array A[]
A = [ 1, 6, 3, 5, 10 ]
B = [ 3, 1, 5 ]
# Given C
C = 2
# Size of arr A
M = len(A)
# Size of arr B
N = len(B)
# Function call
minimumCost(A, B, M, N, C)
# This code is contributed by divyeshrabadiya07
C#
// C# program for the above approach
using System;
class GFG{
// Function to find lower_bound
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;
}
// Function to find length of the
// longest common subsequence
static int findLCS(int[] nums, int N)
{
int k = 0;
for(int i = 0; i < N; i++)
{
// Find position where element
// is to be inserted
int pos = LowerBound(nums, k,
nums[i]);
nums[pos] = nums[i];
if (k == pos)
{
k = pos + 1;
}
}
// Return the length of LCS
return k;
}
// Function to find the minimum cost
// required to convert the sequence A
// exactly same as B
static int minimumCost(int[] A, int[] B,
int M, int N, int C)
{
// Auxiliary array
int[] nums = new int[100000];
// Stores positions of elements of A[]
int[] index = new int[100000];
// Initialize index array with -1
for(int i = 0; i < 100000; i++)
index[i] = -1;
for(int i = 0; i < N; i++)
{
// Update the index array with
// index of corresponding
// elements of B
index[B[i]] = i;
}
int k = 0;
for(int i = 0; i < M; i++)
{
// Place only A's array values
// with its mapped values
// into nums array
if (index[A[i]] != -1)
{
nums[k++] = index[A[i]];
}
}
// Find LCS
int lcs_length = findLCS(nums, k);
// No of elements to be added
// in array A[]
int elements_to_be_added = N - lcs_length;
// Stores minimum cost
int min_cost = elements_to_be_added * C;
// Print the minimum cost
Console.WriteLine(min_cost);
return 0;
}
// Driver code
public static void Main()
{
// Given array A[]
int[] A = { 1, 6, 3, 5, 10 };
int[] B = { 3, 1, 5 };
// Given C
int C = 2;
// Size of arr A
int M = A.Length;
// Size of arr B
int N = B.Length;
// Function call
minimumCost(A, B, M, N, C);
}
}
// This code is contributed by code_hunt
Javascript
2
时间复杂度: O(N * Log N)
辅助空间: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。