📌  相关文章
📜  重新排列给定数组以使其等于另一个给定数组所需的最小成本

📅  最后修改于: 2021-09-17 06:43:15             🧑  作者: Mango

给定两个分别由NM 个整数组成的数组A[]B[]以及一个整数C ,任务是找到使序列AB完全相同(仅由不同元素组成)所需的最小成本对数组A[]执行以下操作:

  • 从数组中删除任何成本为0 的元素。
  • 在数组中的任意位置插入一个新元素,成本为C

例子:

朴素的方法:最简单的方法是使用两个 for 循环擦除数组A[]中不存在于数组B[] 中的所有元素。之后生成数组中剩余元素的所有排列,并为每个序列检查最小成本,使得数组A[]与数组B[] 相同。打印相同的最低成本。

时间复杂度: O(N!*N*M),其中 N 是数组 A[] 的大小,M 是数组 B[] 的大小。
辅助空间: O(1)

高效方法:为了优化上述方法,其思想是首先找到数组A[]B[]的最长公共子序列的长度,并从数组B[]的大小中减去它,得到元素数添加到数组A[] 中。并将数量C添加到每个添加新元素的成本中。因此,总成本由下式给出:

请按照以下步骤解决问题:

  • 创建一个新数组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 现场工作专业课程学生竞争性编程现场课程