Skip to content
Related Articles

Related Articles

Improve Article

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][0] 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 <bits/stdc++.h>
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] = 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[0]);
 
    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




<script>
 
// javascript program for the above approach
var max1 = 1000000000;
 
// Function to calculate sum of lengths
// of two smallest subsets with sum >= K
function MinimumLength(A, N, K)
{
0
    // Sort the array in ascending order
    A.sort();
 
    // Stores suffix sum of the array
    var suffix = Array(N + 1).fill(0);
     
    var i;
    // Update the suffix sum array
    for (i = N - 1; i >= 0; i--)
        suffix[i] = suffix[i + 1] + A[i];
 
    // Stores all dp-states
    var dp = new Array(N + 1);
    for (i = 0; i < N+1; i++)
       dp[i] = new Array(K + 1);
 
    // Initialize all dp-states
    // with a max1imum possible value
    var j;
    for (i = 0; i <= N; i++) {
        for (j = 0; j <= K; j++){
            dp[i][j] = max1;
        }
    };
 
    // Base Case
    dp[N][0] = 0;
 
    // Traverse the array arr[]
    for (i = N - 1; i >= 0; i--) {
 
        // Iterate over the range [0, K]
        for (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]] == max1)
                dp[i][j] = max1;
 
            // 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 (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
 
    var arr = [7, 4, 5, 6, 8];
    var K = 13;
    var N = arr.length;
 
    document.write(MinimumLength(arr, N, K));
 
// This code is contributed by SURENDRA_GANGWAR.
</script>
Output: 
4

 

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

 

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.




My Personal Notes arrow_drop_up
Recommended Articles
Page :