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

📅  最后修改于: 2021-05-14 08:23:08             🧑  作者: Mango

给定大小为N且整数K的数组arr [] ,任务是通过将数组拆分为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 )