# Minimize sum of differences between maximum and minimum elements present in K subsets

• Difficulty Level : Medium
• Last Updated : 18 Jan, 2021

Given an array arr[] of size N and an integer K, the task is to minimize the sum of difference between the maximum and minimum element of each subset by splitting the array into K subsets such that each subset consists of unique array elements only.

Examples:

Input: arr[] = { 6, 3, 8, 1, 3, 1, 2, 2 }, K = 4
Output: 6
Explanation:
One of the optimal ways to split the array into K(= 4) subsets are { { 1, 2 }, { 2, 3 }, { 6, 8 }, { 1, 4 } }.
Sum of difference of maximum and minimum element present in each subset = { (2 – 1) + (3 – 2) + (8 – 6) + (3 – 1) } = 6.
Therefore, the required output is 6

Input: arr[] = { 2, 2, 1, 1 }, K = 1
Output: -1

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Approach: The problem can be solved using Dynamic Programming with bitmasking. Following are the recurrence relations:

mask: ith bit of mask checks if array element is already selected in a subset or not.
l: index of last element selected in a subset.
j: index of current element selected in a subset.

If count of set bits in mask mod (N / K) == 1:

Otherwise,

Follow the steps below to solve the problem:

• Iterate over all possible values of mask, i.e. [0, 2N – 1]
• Initialize an array, say n_z_bits[], to store the count of elements already selected in subsets.
• Use the above recurrence relation and fill all possible dp states of the recurrence relation.
• Finally, print the minimum elements from dp[(1 << N ) - 1].

Below is the implementation of the above approach:

## 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)) `

Output:

```6
```

Time Complexity: O(N* 2N)
Auxiliary Space: O(N * 2N)

My Personal Notes arrow_drop_up
Recommended Articles
Page :