# 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