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

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:**

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the **DSA Self Paced Course** at a student-friendly price and become industry ready. To complete your preparation from learning a language to DS Algo and many more, please refer **Complete Interview Preparation Course****.**

In case you wish to attend **live classes **with experts, please refer **DSA Live Classes for Working Professionals **and **Competitive Programming Live for Students**.

Input:arr[] = { 6, 3, 8, 1, 3, 1, 2, 2 }, K = 4Output:6Explanation:

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 = 1Output:-1

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

mask:i^{th}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:

dp[mask][l] = min(dp[mask][l], dp[mask ^ (1 << l)][j])Otherwise,

dp[mask][j] = min(dp[mask][j], dp[mask ^ (1 << j)][l] + nums[l] - nums[j])

Follow the steps below to solve the problem:

- Iterate over all possible values of
**mask**, i.e.**[0, 2**^{N}– 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* 2^{N})*Auxiliary Space:** O(N * 2 ^{N})*