📜  通过最小化每个子阵列中重复元素的数量,以最小的成本将阵列拆分为子阵列

📅  最后修改于: 2021-05-17 16:35:31             🧑  作者: Mango

给定的阵列ARR []从范围具有N个整数[1,N]和整数K,任务是找到最小可能的成本到阵列分割成可以基于以下条件来实现非空的子阵列:

  • 如果子数组中没有唯一元素,则成本为K。
  • 否则,代价是K +每个重复元素的频率总和。

例子:

天真的方法:解决问题的最简单方法是生成所有可能的子数组,以预先计算并存储其各自的成本。然后,计算可在阵列上执行的每个可能拆分的成本。最后,打印所有拆分的最低成本。
请按照以下步骤解决问题:

  1. 根据上述条件预先计算每个子阵列的成本。
  2. 生成可以在阵列上执行的所有可能的拆分。
  3. 对于每个拆分,请计算每个拆分器子数组的总成本。
  4. 保持最低的总生成成本,最后打印最小的金额。

时间复杂度: O(N!)
辅助空间: O(N)

高效方法:想法是使用动态编程来优化上述方法。请按照以下步骤解决问题:

  1. 在所有索引处使用INT_MAX初始化长度为N的数组dp []
  2. 初始化数组的第一个元素。
  3. 对于任何索引i ,数组dp [i]表示将数组分为从0到i的子数组的最小开销。
  4. 对于每个索引i ,计算从i到N的所有索引的最小成本。
  5. 对数组的所有元素重复此过程
  6. 返回dp []的最后一个元素,以获取拆分数组的最低成本。

下面是上述方法的实现:

C++
// C++ program for the above approach
  
#include 
#define ll long long
using namespace std;
  
// Function to find the minimum cost
// of splitting the array into subarrays
int findMinCost(vector& a, int k)
{
    // Size of the array
    int n = (int)a.size();
  
    // Get the maximum element
    int max_ele = *max_element(a.begin(),
                               a.end());
  
    // dp[] will store the minimum cost
    // upto index i
    ll dp[n + 1];
  
    // Initialize the result array
    for (int i = 1; i <= n; ++i)
        dp[i] = INT_MAX;
  
    // Initialise the first element
    dp[0] = 0;
  
    for (int i = 0; i < n; ++i) {
  
        // Create the frequency array
        int freq[max_ele + 1];
  
        // Initialize frequency array
        memset(freq, 0, sizeof freq);
  
        for (int j = i; j < n; ++j) {
  
            // Update the frequency
            freq[a[j]]++;
            int cost = 0;
  
            // Counting the cost of
            // the duplicate element
            for (int x = 0;
                 x <= max_ele; ++x) {
                cost += (freq[x] == 1)
                            ? 0
                            : freq[x];
            }
  
            // Minimum cost of operation
            // from 0 to j
            dp[j + 1] = min(dp[i] + cost + k,
                            dp[j + 1]);
        }
    }
  
    // Total cost of the array
    return dp[n];
}
  
// Driver Code
int main()
{
    vector arr = { 1, 2, 1, 1, 1 };
  
    // Given cost K
    int K = 2;
  
    // Function Call
    cout << findMinCost(arr, K);
  
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
class GFG {
  
// Function to find the 
// minimum cost of splitting 
// the array into subarrays
static long findMinCost(int[] a, 
                        int k, int n)
{
  // Get the maximum element
  int max_ele = Arrays.stream(a).max().getAsInt();
  
  // dp[] will store the minimum cost
  // upto index i
  long[] dp = new long[n + 1];
  
  // Initialize the result array
  for (int i = 1; i <= n; ++i)
    dp[i] = Integer.MAX_VALUE;
  
  // Initialise the first element
  dp[0] = 0;
  
  for (int i = 0; i < n; ++i) 
  {
    // Create the frequency array
    int[] freq = new int[max_ele + 1];
  
    for (int j = i; j < n; ++j) 
    {
      // Update the frequency
      freq[a[j]]++;
      int cost = 0;
  
      // Counting the cost of
      // the duplicate element
      for (int x = 0; x <= max_ele; ++x) 
      {
        cost += (freq[x] == 1) ? 0 : 
                 freq[x];
      }
  
      // Minimum cost of operation
      // from 0 to j
      dp[j + 1] = Math.min(dp[i] + cost + k, 
                           dp[j + 1]);
    }
  }
  
  // Total cost of the array
  return dp[n];
}
  
// Driver Code
public static void main(String[] args)
{
  int[] arr = {1, 2, 1, 1, 1};
  
  // Given cost K
  int K = 2;
  int n = arr.length;
    
  // Function Call
  System.out.print(findMinCost(arr, 
                               K, n));
}
}
  
// This code is contributed by gauravrajput1


Python3
# Python3 program for the above approach
import sys
  
# Function to find the
# minimum cost of splitting
# the array into subarrays
def findMinCost(a, k, n):
      
    # Get the maximum element
    max_ele = max(a)
  
    # dp will store the minimum cost
    # upto index i
    dp = [0] * (n + 1)
  
    # Initialize the result array
    for i in range(1, n + 1):
        dp[i] = sys.maxsize
  
    # Initialise the first element
    dp[0] = 0
  
    for i in range(0, n):
          
        # Create the frequency array
        freq = [0] * (max_ele + 1)
  
        for j in range(i, n):
              
            # Update the frequency
            freq[a[j]] += 1
            cost = 0
  
            # Counting the cost of
            # the duplicate element
            for x in range(0, max_ele + 1):
                cost += (0 if (freq[x] == 1) else
                               freq[x])
  
            # Minimum cost of operation
            # from 0 to j
            dp[j + 1] = min(dp[i] + cost + k,
                            dp[j + 1])
  
    # Total cost of the array
    return dp[n]
  
# Driver Code
if __name__ == '__main__':
      
    arr = [ 1, 2, 1, 1, 1 ];
  
    # Given cost K
    K = 2;
    n = len(arr);
  
    # Function call
    print(findMinCost(arr, K, n));
  
# This code is contributed by Amit Katiyar


C#
// C# program for the above approach
using System;
using System.Linq;
class GFG{
  
// Function to find the 
// minimum cost of splitting 
// the array into subarrays
static long findMinCost(int[] a, 
                        int k, int n)
{
  // Get the maximum element
  int max_ele = a.Max();
  
  // []dp will store the minimum cost
  // upto index i
  long[] dp = new long[n + 1];
  
  // Initialize the result array
  for (int i = 1; i <= n; ++i)
    dp[i] = int.MaxValue;
  
  // Initialise the first element
  dp[0] = 0;
  
  for (int i = 0; i < n; ++i) 
  {
    // Create the frequency array
    int[] freq = new int[max_ele + 1];
  
    for (int j = i; j < n; ++j) 
    {
      // Update the frequency
      freq[a[j]]++;
      int cost = 0;
  
      // Counting the cost of
      // the duplicate element
      for (int x = 0; x <= max_ele; ++x) 
      {
        cost += (freq[x] == 1) ? 0 : 
                 freq[x];
      }
  
      // Minimum cost of operation
      // from 0 to j
      dp[j + 1] = Math.Min(dp[i] + cost + k, 
                           dp[j + 1]);
    }
  }
  
  // Total cost of the array
  return dp[n];
}
  
// Driver Code
public static void Main(String[] args)
{
  int[] arr = {1, 2, 1, 1, 1};
  
  // Given cost K
  int K = 2;
  int n = arr.Length;
    
  // Function Call
  Console.Write(findMinCost(arr, 
                               K, n));
}
}
  
// This code is contributed by shikhasingrajput


输出:
6

时间复杂度: O(N 3 ),其中N是给定数组的大小。
辅助空间: O(N)