# Sum of length of two smallest subsets possible from a given array with sum at least K

• Difficulty Level : Hard
• Last Updated : 25 May, 2021

Given an array arr[] consisting of N integers and an integer K, the task is to find the sum of the length of the two smallest unique subsets having sum of its elements at least K.

Examples:

Input: arr[] = {2, 4, 5, 6, 7, 8}, K = 16
Output: 6
Explanation:
The subsets {2, 6, 8} and {4, 5, 7} are the two smallest subsets with sum K(= 16).
Therefore, the sum of the lengths of both these subsets = 3 + 3 = 6.

Input: arr[] = {14, 3, 7, 8, 9, 7, 12, 15, 10, 6}, K = 40
Output: 8

Approach: The given problem can be solved based on the following observations:

• Sorting the array reduces the problem to choosing a subarray whose sum is at least K between the range of indices [i, N], and then check, if the sum of the remaining array elements in the range of indices [i, N] is K or not.
• To implement the above idea, a 2D array, say dp[][], is used such that dp[i][j] stores the minimum sum of the subset over the range of indices [i, N] having a value at least j. Then the transition state is similar to 0/1 Knapsack that can be defined as:
• If the value of arr[i] is greater than j, then update dp[i][j] to arr[i].
• Otherwise, update dp[i][j] to the minimum of dp[i + 1][j] and (dp[i + 1][j – arr[i]] + arr[i]).

Follow the steps below to solve the problem:

• Sort the array in ascending order.
• Initialize an array, say suffix[], and store the suffix sum of the array arr[] in it.
• Initialize a 2D array, say dp[][], such that dp[i][j]  stores the minimum sum of the subset over the range of indices [i, N] having a value at least j.
• Initialize dp[N] as 0 and all other states as INT_MAX.
• Traverse the array arr[i] in reverse order and perform the following steps:
• Iterate over the range of indices [0, K] in reverse order and perform the following operations:
• If the value of arr[i] is at least j, then update the value of dp[i][j] as arr[i] as the current state has sum at least j. Now, continue the iteration.
• If the value of next state, i.e., dp[i + 1][j – arr[i]] is INT_MAX, then update dp[i][j] as INT_MAX.
• Otherwise, update dp[i][j] as the minimum of dp[i + 1][j] and (dp[i + 1][j – arr[i]] + arr[i]) to store the sum of all values having sum at least j.
• Now, traverse the array suffix[] in reverse order and if the value of (suffix[i] – dp[i][K]) is at least K, then print (N – i) as the sum of the size of the two smallest subsets formed and break out of the loop.
• Otherwise, print “-1”.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach``#include ``using` `namespace` `std;``const` `int` `MAX = 1e9;` `// Function to calculate sum of lengths``// of two smallest subsets with sum >= K``int` `MinimumLength(``int` `A[], ``int` `N, ``int` `K)``{``    ``// Sort the array in ascending order``    ``sort(A, A + N);` `    ``// Stores suffix sum of the array``    ``int` `suffix[N + 1] = { 0 };` `    ``// Update the suffix sum array``    ``for` `(``int` `i = N - 1; i >= 0; i--)``        ``suffix[i] = suffix[i + 1] + A[i];` `    ``// Stores all dp-states``    ``int` `dp[N + 1][K + 1];` `    ``// Initialize all dp-states``    ``// with a maximum possible value``    ``for` `(``int` `i = 0; i <= N; i++)``        ``for` `(``int` `j = 0; j <= K; j++)``            ``dp[i][j] = MAX;` `    ``// Base Case``    ``dp[N] = 0;` `    ``// Traverse the array arr[]``    ``for` `(``int` `i = N - 1; i >= 0; i--) {` `        ``// Iterate over the range [0, K]``        ``for` `(``int` `j = K; j >= 0; j--) {` `            ``// If A[i] is equal to at``            ``// least the required sum``            ``// j for the current state``            ``if` `(j <= A[i]) {``                ``dp[i][j] = A[i];``                ``continue``;``            ``}` `            ``// If the next possible``            ``// state doesn't exist``            ``if` `(dp[i + 1][j - A[i]] == MAX)``                ``dp[i][j] = MAX;` `            ``// Otherwise, update the current``            ``// state to the minimum of the``            ``// next state and state including``            ``// the current element A[i]``            ``else``                ``dp[i][j] = min(dp[i + 1][j],``                               ``dp[i + 1][j - A[i]] + A[i]);``        ``}``    ``}` `    ``// Traverse the suffix sum array``    ``for` `(``int` `i = N - 1; i >= 0; i--) {` `        ``// If suffix[i] - dp[i][K] >= K``        ``if` `(suffix[i] - dp[i][K] >= K) {` `            ``// Sum of lengths of the two``            ``// smallest subsets is obtained``            ``return` `N - i;``        ``}``    ``}` `    ``// Return -1, if there doesn't``    ``// exist any subset of sum >= K``    ``return` `-1;``}` `// Driver Code``int` `main()``{``    ``int` `arr[] = { 7, 4, 5, 6, 8 };``    ``int` `K = 13;``    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr);` `    ``cout << MinimumLength(arr, N, K);` `    ``return` `0;``}`

## Java

 `// Java program for the above approach``import` `java.io.*;``import` `java.lang.*;``import` `java.util.*;` `class` `GFG{` `static` `int` `MAX = (``int``)(1e9);` `// Function to calculate sum of lengths``// of two smallest subsets with sum >= K``static` `int` `MinimumLength(``int` `A[], ``int` `N, ``int` `K)``{``    ` `    ``// Sort the array in ascending order``    ``Arrays.sort(A);``    ` `    ``// Stores suffix sum of the array``    ``int` `suffix[] = ``new` `int``[N + ``1``];` `    ``// Update the suffix sum array``    ``for``(``int` `i = N - ``1``; i >= ``0``; i--)``        ``suffix[i] = suffix[i + ``1``] + A[i];` `    ``// Stores all dp-states``    ``int` `dp[][] = ``new` `int``[N + ``1``][K + ``1``];` `    ``// Initialize all dp-states``    ``// with a maximum possible value``    ``for``(``int` `i = ``0``; i <= N; i++)``        ``for``(``int` `j = ``0``; j <= K; j++)``            ``dp[i][j] = MAX;` `    ``// Base Case``    ``dp[N][``0``] = ``0``;` `    ``// Traverse the array arr[]``    ``for``(``int` `i = N - ``1``; i >= ``0``; i--)``    ``{``        ` `        ``// Iterate over the range [0, K]``        ``for``(``int` `j = K; j >= ``0``; j--)``        ``{``            ` `            ``// If A[i] is equal to at``            ``// least the required sum``            ``// j for the current state``            ``if` `(j <= A[i])``            ``{``                ``dp[i][j] = A[i];``                ``continue``;``            ``}` `            ``// If the next possible``            ``// state doesn't exist``            ``if` `(dp[i + ``1``][j - A[i]] == MAX)``                ``dp[i][j] = MAX;` `            ``// Otherwise, update the current``            ``// state to the minimum of the``            ``// next state and state including``            ``// the current element A[i]``            ``else``                ``dp[i][j] = Math.min(dp[i + ``1``][j],``                                    ``dp[i + ``1``][j - A[i]]``                                         ``+ A[i]);``        ``}``    ``}` `    ``// Traverse the suffix sum array``    ``for``(``int` `i = N - ``1``; i >= ``0``; i--)``    ``{``        ` `        ``// If suffix[i] - dp[i][K] >= K``        ``if` `(suffix[i] - dp[i][K] >= K)``        ``{``            ` `            ``// Sum of lengths of the two``            ``// smallest subsets is obtained``            ``return` `N - i;``        ``}``    ``}` `    ``// Return -1, if there doesn't``    ``// exist any subset of sum >= K``    ``return` `-``1``;``}` `// Driver Code``public` `static` `void` `main(String[] args)``{``    ``int` `arr[] = { ``7``, ``4``, ``5``, ``6``, ``8` `};``    ``int` `K = ``13``;``    ``int` `N = arr.length;` `    ``System.out.println(MinimumLength(arr, N, K));``}``}` `// This code is contributed by Kingash`

## Python3

 `# Python3 program for the above approach``MAX` `=` `1e9` `# Function to calculate sum of lengths``# of two smallest subsets with sum >= K``def` `MinimumLength(A, N, K):``    ` `    ``# Sort the array in ascending order``    ``A.sort()` `    ``# Stores suffix sum of the array``    ``suffix ``=` `[``0``] ``*` `(N ``+` `1``)` `    ``# Update the suffix sum array``    ``for` `i ``in` `range``(N ``-` `1``, ``-``1``, ``-``1``):``        ``suffix[i] ``=` `suffix[i ``+` `1``] ``+` `A[i]` `    ``# Stores all dp-states``    ``dp ``=` `[[``0``] ``*` `(K ``+` `1``)] ``*` `(N ``+` `1``)` `    ``# Initialize all dp-states``    ``# with a maximum possible value``    ``for` `i ``in` `range``(N ``+` `1``):``        ``for` `j ``in` `range``(K ``+` `1``):``            ``dp[i][j] ``=` `MAX` `    ``# Base Case``    ``dp[N][``0``] ``=` `0` `    ``# Traverse the array arr[]``    ``for` `i ``in` `range``(N ``-` `1``, ``-``1``, ``-``1``):` `        ``# Iterate over the range [0, K]``        ``for` `j ``in` `range``(K, ``-``1``, ``-``1``):``            ` `            ``# If A[i] is equal to at``            ``# least the required sum``            ``# j for the current state``            ``if` `(j <``=` `A[i]) :``                ``dp[i][j] ``=` `A[i]``                ``continue``            ` `            ``# If the next possible``            ``# state doesn't exist``            ``if` `(dp[i ``+` `1``][j ``-` `A[i]] ``=``=` `MAX``):``                ``dp[i][j] ``=` `MAX` `            ``# Otherwise, update the current``            ``# state to the minimum of the``            ``# next state and state including``            ``# the current element A[i]``            ``else` `:``                ``dp[i][j] ``=` `min``(dp[i ``+` `1``][j],``                               ``dp[i ``+` `1``][j ``-` `A[i]] ``+` `A[i])``        ` `    ``# Traverse the suffix sum array``    ``for` `i ``in` `range``(N ``-` `1``, ``-``1``, ``-``1``):` `        ``# If suffix[i] - dp[i][K] >= K``        ``if` `(suffix[i] ``-` `dp[i][K] >``=` `K):` `            ``# Sum of lengths of the two``            ``# smallest subsets is obtained``            ``return` `N ``-` `i``        ` `    ``# Return -1, if there doesn't``    ``# exist any subset of sum >= K``    ``return` `-``1` `# Driver Code``arr ``=` `[ ``7``, ``4``, ``5``, ``6``, ``8` `]``K ``=` `13``N ``=` `len``(arr)` `print``(MinimumLength(arr, N, K))` `# This code is contributed by splevel62`

## C#

 `// C# program for the above approach``using` `System;` `class` `GFG{` `static` `int` `MAX = (``int``)(1e9);` `// Function to calculate sum of lengths``// of two smallest subsets with sum >= K``static` `int` `MinimumLength(``int``[] A, ``int` `N, ``int` `K)``{``    ` `    ``// Sort the array in ascending order``    ``Array.Sort(A);` `    ``// Stores suffix sum of the array``    ``int``[] suffix = ``new` `int``[N + 1];` `    ``// Update the suffix sum array``    ``for``(``int` `i = N - 1; i >= 0; i--)``        ``suffix[i] = suffix[i + 1] + A[i];` `    ``// Stores all dp-states``    ``int``[,] dp = ``new` `int``[N + 1, K + 1];` `    ``// Initialize all dp-states``    ``// with a maximum possible value``    ``for``(``int` `i = 0; i <= N; i++)``        ``for``(``int` `j = 0; j <= K; j++)``            ``dp[i, j] = MAX;` `    ``// Base Case``    ``dp[N, 0] = 0;` `    ``// Traverse the array arr[]``    ``for``(``int` `i = N - 1; i >= 0; i--)``    ``{``        ` `        ``// Iterate over the range [0, K]``        ``for``(``int` `j = K; j >= 0; j--)``        ``{``            ` `            ``// If A[i] is equal to at``            ``// least the required sum``            ``// j for the current state``            ``if` `(j <= A[i])``            ``{``                ``dp[i, j] = A[i];``                ``continue``;``            ``}` `            ``// If the next possible``            ``// state doesn't exist``            ``if` `(dp[i + 1, j - A[i]] == MAX)``                ``dp[i, j] = MAX;` `            ``// Otherwise, update the current``            ``// state to the minimum of the``            ``// next state and state including``            ``// the current element A[i]``            ``else``                ``dp[i, j] = Math.Min(dp[i + 1, j],``                                    ``dp[i + 1, j - A[i]]``                                         ``+ A[i]);``        ``}``    ``}` `    ``// Traverse the suffix sum array``    ``for``(``int` `i = N - 1; i >= 0; i--)``    ``{``        ` `        ``// If suffix[i] - dp[i][K] >= K``        ``if` `(suffix[i] - dp[i, K] >= K)``        ``{``            ` `            ``// Sum of lengths of the two``            ``// smallest subsets is obtained``            ``return` `N - i;``        ``}``    ``}` `    ``// Return -1, if there doesn't``    ``// exist any subset of sum >= K``    ``return` `-1;``}` `// Driver Code``public` `static` `void` `Main(``string``[] args)``{``    ``int``[] arr = { 7, 4, 5, 6, 8 };``    ``int` `K = 13;``    ``int` `N = arr.Length;` `    ``Console.WriteLine(MinimumLength(arr, N, K));``}``}` `// This code is contributed by ukasp`

## Javascript

 ``

Output:

`4`

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

My Personal Notes arrow_drop_up