📌  相关文章
📜  最小化 K 个子集中存在的最大和最小元素之间的差异总和

📅  最后修改于: 2021-09-05 11:46:24             🧑  作者: Mango

给定一个大小为N的数组 arr[]和一个整数K ,任务是通过将数组拆分为 K个子集,使每个子集仅由唯一的数组元素组成,从而最小化每个子集的最大和最小元素之间的差值之和。

例子:

方法:该问题可以使用带有位掩码的动态规划来解决。以下是递推关系:

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

  • 迭代 mask 的所有可能值,即[0, 2 N – 1]
  • 初始化一个数组,比如n_z_bits[] ,以存储子集中已经选择的元素的数量。
  • 使用上面的递推关系并填充递推关系的所有可能的dp状态。
  • 最后,打印dp[(1 << N ) – 1] 中的最小元素。

下面是上述方法的实现:

Python3
# Python program to implement
# the above approach
from itertools import permutations 
from itertools import combinations
  
# Function to minimize the sum of
# difference between maximums and
# minimums of K subsets of an array
def MinimizeSum(nums, k):
  
    # Stores count of elements
    # in an array
    n = len(nums)
      
    # Base Case
    if k == n:
        return 0
  
    # Initialize DP[][] array
    dp = [[float("inf")] * n for _ in range(1 << n)]
  
    # Sort the array
    nums.sort()
  
    # Mark i-th element
    # as not selected
    for i in range(n):
        dp[1 << i][i] = 0
  
    # Iterate over all possible
    # values of mask
    for mask in range(1 << n):
  
        # Store count of set bits
        # in mask
        n_z_bits = []
          
  
        # Store index of element which is 
        # already selected in a subset
        for p, c in enumerate(bin(mask)): 
            if c == "1":
                temp = len(bin(mask)) - p - 1
                n_z_bits.append(temp)
  
        # If count of set bits in mask
                # mod (n // k) equal to 1
        if len(n_z_bits) % (n//k) == 1:
            for j, l in permutations(n_z_bits, 2):
                temp = dp[mask ^ (1 << l)][j]
                dp[mask][l] = min(dp[mask][l], temp)
  
        else:
            for j, l in combinations(n_z_bits, 2):
                if nums[j] != nums[l]:
  
                    # Check if l-th element 
                    # is already selected or not
                    mask_t = mask ^ (1 << l)
  
                    temp = (dp[mask_t][j] + 
                             nums[j] - nums[l])
  
                    # Update dp[mask][l]        
                    dp[mask][l] = min(dp[mask][l],
                                            temp)
      
    # Return minimum element 
    # from dp[(1 << N) - 1]
    if min(dp[-1]) != float("inf"):
        return min(dp[-1])
      
    # If dp[-1] is inf then the 
    # partition is not possible 
    else: 
        return -1
      
# Driver Code
if __name__ == "__main__":
    # Given array
    arr = [ 6, 3, 8, 1, 3, 1, 2, 2 ]
    K = 4
  
    # Function call
    print(MinimizeSum(arr, K))


输出:
6

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

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live