Skip to content
geeksforgeeks
  • Tutorials
    • Python
    • Java
    • Data Structures & Algorithms
    • ML & Data Science
    • Interview Corner
    • Programming Languages
    • Web Development
    • CS Subjects
    • DevOps And Linux
    • School Learning
    • Practice Coding Problems
  • Courses
    • DSA to Development
    • Get IBM Certification
    • Newly Launched!
      • Master Django Framework
      • Become AWS Certified
    • For Working Professionals
      • Interview 101: DSA & System Design
      • Data Science Training Program
      • JAVA Backend Development (Live)
      • DevOps Engineering (LIVE)
      • Data Structures & Algorithms in Python
    • For Students
      • Placement Preparation Course
      • Data Science (Live)
      • Data Structure & Algorithm-Self Paced (C++/JAVA)
      • Master Competitive Programming (Live)
      • Full Stack Development with React & Node JS (Live)
    • Full Stack Development
    • Data Science Program
    • All Courses
  • DSA
  • Interview Problems on DP
  • Practice DP
  • MCQs on DP
  • Tutorial on Dynamic Programming
  • Optimal Substructure
  • Overlapping Subproblem
  • Memoization
  • Tabulation
  • Tabulation vs Memoization
  • 0/1 Knapsack
  • Unbounded Knapsack
  • Subset Sum
  • LCS
  • LIS
  • Coin Change
  • Word Break
  • Egg Dropping Puzzle
  • Matrix Chain Multiplication
  • Palindrome Partitioning
  • DP on Arrays
  • DP with Bitmasking
  • Digit DP
  • DP on Trees
  • DP on Graph
Open In App
Next Article:
Coin Change - Minimum Coins to Make Sum
Next article icon

Length of longest subset consisting of A 0s and B 1s from an array of strings

Last Updated : 16 Nov, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an array arr[] consisting of binary strings, and two integers a and b, the task is to find the length of the longest subset consisting of at most a 0s and b 1s.

Examples:

Input: arr[] = ["1" ,"0" ,"0001" ,"10" ,"111001"], a = 5, b = 3
Output: 4
Explanation: 
One possible way is to select the subset [arr[0], arr[1], arr[2], arr[3]].
Total number of 0s and 1s in all these strings are 5 and 3 respectively.
Also, 4 is the length of the longest subset possible.

Input: arr[] = ["0" ,"1" ,"10"], a = 1, b = 1
Output: 2
Explanation: 
One possible way is to select the subset [arr[0], arr[1]].
Total number of 0s and 1s in all these strings is 1 and 1 respectively.
Also, 2 is the length of the longest subset possible.

Table of Content

  • Using Recursion – O(2^n) Time and O(n) Space
  • Using Memoization - O(n*a*b) Time and O(n*a*b) Space
  • Using Bottom-Up DP (Tabulation) - O(n*a*b) Time and O(n*a*b) Space

Using Recursion – O(2^n) Time and O(n) Space

A simple approach is to consider all the possible subsets of strings and calculating the total counts of zeros and ones in each subset. Consider the only subsets that contain exactly a zeros and b ones. From all such subsets, pick the subset with maximum length.

Case 1: Exclude the current string

  • findMaxSubset(index, a, b) = findMaxSubset(index + 1, a, b)

Case 2: Include the current string: Include the current string in the subset if its count of zeros and ones is within the remaining limits (a and b)

  • findMaxSubset(index, a, b) = 1 + findMaxSubset(index + 1, a- zeroCount, b - oneCount), where zeroCount and oneCount is the count of zeros and ones of current string.
C++
// C++ program to find the length of the longest subset // using recursion  #include <iostream> #include <vector> using namespace std;  int findMaxSubsetSize(int index, int n, vector<int> 				&zeroCounts, vector<string> &strs, int maxZeros, int maxOnes) {      // Base case: if we've processed all strings, return 0     if (index >= n)         return 0;      // Option 1: Skip the current string     int maxSubset = findMaxSubsetSize(index + 1,  				n, zeroCounts, strs, maxZeros, maxOnes);      int zeroCount = zeroCounts[index];     int oneCount = strs[index].size() - zeroCount;      // Option 2: Include the current string if it     // doesn't exceed the max zeros and ones allowed     if (zeroCount <= maxZeros && oneCount <= maxOnes) {         int includeCurrent =             1 + findMaxSubsetSize(index + 1, n, zeroCounts,  			strs, maxZeros - zeroCount, maxOnes - oneCount);         maxSubset = max(maxSubset, includeCurrent);     }      return   maxSubset; }  int maxSubsetSize(vector<string> &strs, int maxZeros,                   int maxOnes) {     int n = strs.size();      // Precompute the count of zeros     // in each string and store in zeroCounts array     vector<int> zeroCounts(n, 0);     for (int i = 0; i < n; i++) {         int countZeros = 0;         for (char c : strs[i]) {             if (c == '0')                 countZeros++;         }         zeroCounts[i] = countZeros;     }     return findMaxSubsetSize(0, n, zeroCounts, strs,                               maxZeros, maxOnes); }  int main() {        vector<string> arr = {"1", "0", "0001", "10", "111001"};     int a = 5, b = 3;     int res = maxSubsetSize(arr, a, b);     cout << res;     return 0; } 
Java
// Java program to find the length of the longest subset // using recursion  import java.util.*; class GfG {     static int findMaxSubsetSize(int index, int n,                              int[] zeroCounts,                              String[] strs, int maxZeros,                              int maxOnes) {          // Base case: if we've processed all strings, return         // 0         if (index >= n)             return 0;          // Option 1: Skip the current string         int maxSubset             = findMaxSubsetSize(index + 1, n, zeroCounts, strs,                             maxZeros, maxOnes);          int zeroCount = zeroCounts[index];         int oneCount = strs[index].length() - zeroCount;          // Option 2: Include the current string if it         // doesn't exceed the max zeros and ones allowed         if (zeroCount <= maxZeros && oneCount <= maxOnes) {             int includeCurrent                 = 1                   + findMaxSubsetSize(index + 1, n, zeroCounts,                                   strs,                                   maxZeros - zeroCount,                                   maxOnes - oneCount);             maxSubset = Math.max(maxSubset, includeCurrent);         }         return maxSubset;     }      static int maxSubsetSize(String[] strs, int maxZeros,                            int maxOnes) {         int n = strs.length;            // Precompute the count of zeros in each string and         // store in zeroCounts array         int[] zeroCounts = new int[n];         for (int i = 0; i < n; i++) {             int countZeros = 0;             for (char c : strs[i].toCharArray()) {                 if (c == '0')                     countZeros++;             }             zeroCounts[i] = countZeros;         }          // Start the recursive helper function from the         // first string         return findMaxSubsetSize(0, n, zeroCounts, strs,                              maxZeros, maxOnes);     }      public static void main(String[] args) {          String[] arr = { "1", "0", "0001", "10", "111001" };         int a = 5, b = 3;         int res = maxSubsetSize(arr, a, b);         System.out.println(res);     } } 
Python
# Python program to find the length of the longest subset # using recursion from typing import List  def findMaxSubsetSize(index: int, n: int, zeroCounts: List[int],\                       strs: List[str], maxZeros: int, maxOnes: int) -> int:        # Base case: if we've processed all strings, return 0     if index >= n:         return 0      # Option 1: Skip the current string     maxSubset = findMaxSubsetSize(index + 1, n, \                                   zeroCounts, strs, maxZeros, maxOnes)      zeroCount = zeroCounts[index]     oneCount = len(strs[index]) - zeroCount      # Option 2: Include the current string if it doesn't      # exceed the max zeros and ones allowed     if zeroCount <= maxZeros and oneCount <= maxOnes:         includeCurrent = 1 + findMaxSubsetSize(index + 1, n, \ 		zeroCounts, strs, maxZeros - zeroCount, maxOnes - oneCount)         maxSubset = max(maxSubset, includeCurrent)      return maxSubset  def maxSubsetSize(strs: List[str], maxZeros: int, maxOnes: int) -> int:     n = len(strs)      # Precompute the count of zeros in each      # string and store in zeroCounts array     zeroCounts = [s.count('0') for s in strs]      # Start the recursive helper function      # from the first string     return findMaxSubsetSize(0, n, zeroCounts, strs, maxZeros, maxOnes)  arr = ["1", "0", "0001", "10", "111001"] a, b = 5, 3 res = maxSubsetSize(arr, a, b) print(res) 
C#
// C# program to find the length of the longest subset // using recursion  using System;  class GfG {     static int findMaxSubsetSize(int index, int n,                              int[] zeroCounts,                              string[] strs, int maxZeros,                              int maxOnes) {                // Base case: if we've processed all strings, return         // 0         if (index >= n)             return 0;           // Option 1: Skip the current string         int maxSubset             = findMaxSubsetSize(index + 1, n, zeroCounts, strs,                             maxZeros, maxOnes);          int zeroCount = zeroCounts[index];         int oneCount = strs[index].Length - zeroCount;          // Option 2: Include the current string if it         // doesn't exceed the max zeros and ones allowed         if (zeroCount <= maxZeros && oneCount <= maxOnes) {             int includeCurrent                 = 1                   + findMaxSubsetSize(index + 1, n, zeroCounts,                                   strs,                                   maxZeros - zeroCount,                                   maxOnes - oneCount);             maxSubset = Math.Max(maxSubset, includeCurrent);         }                 return maxSubset;     }      static int maxSubsetSize(string[] strs, int maxZeros,                            int maxOnes) {         int n = strs.Length;            // Precompute the count of zeros in each string and         // store in zeroCounts array         int[] zeroCounts = new int[n];         for (int i = 0; i < n; i++) {             int countZeros = 0;             foreach(char c in strs[i]) {                 if (c == '0')                     countZeros++;             }             zeroCounts[i] = countZeros;         }          // Start the recursive helper function from the         // first string         return findMaxSubsetSize(0, n, zeroCounts, strs,                              maxZeros, maxOnes);     }      static void Main() {         string[] arr = { "1", "0", "0001", "10", "111001" };         int a = 5, b = 3;         int res = maxSubsetSize(arr, a, b);         Console.WriteLine(res);     } } 
JavaScript
// JavaScript program to find the length of the longest // subset using recursion  function findMaxSubsetSize(index, n, zeroCounts, strs, maxZeros,                        maxOnes) {                             // Base case: if we've processed all strings, return 0     if (index >= n) {         return 0;     }          // Option 1: Skip the current string     let maxSubset         = findMaxSubsetSize(index + 1, n, zeroCounts, strs,                         maxZeros, maxOnes);      let zeroCount = zeroCounts[index];     let oneCount = strs[index].length - zeroCount;      // Option 2: Include the current string if it doesn't     // exceed the max zeros and ones allowed     if (zeroCount <= maxZeros && oneCount <= maxOnes) {         let includeCurrent             = 1               + findMaxSubsetSize(index + 1, n, zeroCounts,                               strs, maxZeros - zeroCount,                               maxOnes - oneCount);         maxSubset = Math.max(maxSubset, includeCurrent);     }         return maxSubset; }  function maxSubsetSize(strs, maxZeros, maxOnes) {     const n = strs.length;       // Precompute the count of zeros in each string and     // store in zeroCounts array     const zeroCounts         = strs.map(str => str.split("0").length - 1);      // Start the recursive helper function from the first     // string     return findMaxSubsetSize(0, n, zeroCounts, strs, maxZeros,                          maxOnes); }  const arr = [ "1", "0", "0001", "10", "111001" ]; const a = 5, b = 3; const res = maxSubsetSize(arr, a, b); console.log(res); 

Output
4

Using Memoization - O(n*a*b) Time and O(n*a*b) Space

If we notice carefully, we can observe that the above recursive solution holds the following two properties of Dynamic Programming.

1. Optimal Substructure: The solution to the problem of finding the maximum subset of strings that satisfy exactly a zeros and b ones can be derived from the optimal solutions of smaller subproblems.

2. Overlapping Subproblems: When implementing a recursive approach to solve the problem of selecting strings with exactly a zeros and b ones, we observe that many subproblems are computed multiple times. Specifically, when we recursively solve for findMaxSubset(index, a, b), where a and b represent the remaining number of zeros and ones, the same subproblems might be recomputed several times.

  • The recursive solution involves changing three parameters: the current index and the remaining count of zeros (a) and remaining count of ones (b). We need to track these three parameters, so we create a 3D array of size (n+1)x(a+1)x(b+1) because the value of n will be in range of [0, n] and remaining count of a will be in range [0, a] and remaining count of b will be in range [0, b].
  • We initialize the 3D array with -1 to indicate that no subproblems have been computed yet.
  • we check if the value at memo[n][a][b] is -1. if it is, we proceed to compute the result. otherwise, we return the stored result.
C++
// C++ program to find the length of the longest subset // using memoization  #include <iostream> #include <vector> using namespace std;  int findMaxSubsetSize(int index, int n, vector<int> &zeroCounts,                        vector<string> &strs, int maxZeros, int maxOnes,                   vector<vector<vector<int>>> &memo) {      // Base case: if we've processed all strings, return 0     if (index >= n)         return 0;      // if this state has already     //  been computed, return its stored result     if (memo[index][maxZeros][maxOnes] != -1)         return memo[index][maxZeros][maxOnes];      // Option 1: Skip the current string     int maxSubset = findMaxSubsetSize(index + 1, n,                                        zeroCounts, strs,                                        maxZeros, maxOnes, memo);      int zeroCount = zeroCounts[index];     int oneCount = strs[index].size() - zeroCount;      // Option 2: Include the current string if it     // doesn't exceed the max zeros and ones allowed     if (zeroCount <= maxZeros && oneCount <= maxOnes) {         int includeCurrent =             1 + findMaxSubsetSize(index + 1, n,  			zeroCounts, strs, maxZeros - zeroCount, maxOnes - oneCount, memo);         maxSubset = max(maxSubset, includeCurrent);     }      // Memoize the result for the current state and return it     return memo[index][maxZeros][maxOnes] = maxSubset; }  int maxSubsetSize(vector<string> &strs, int maxZeros, int maxOnes) {     int n = strs.size();      // 3D DP array to memoize results,     // initialized to -1 for uncomputed states     vector<vector<vector<int>>> memo(n + 1, 	vector<vector<int>>(maxZeros + 1, vector<int>(maxOnes + 1, -1)));      // Precompute the count of zeros     // in each string and store in zeroCounts array     vector<int> zeroCounts(n, 0);     for (int i = 0; i < n; i++) {         int countZeros = 0;         for (char c : strs[i]) {             if (c == '0')                 countZeros++;         }         zeroCounts[i] = countZeros;     }     return findMaxSubsetSize(0, n, zeroCounts,                               strs, maxZeros, maxOnes, memo); }  int main() {        vector<string> arr = {"1", "0", "0001", "10", "111001"};     int a = 5, b = 3;     int res = maxSubsetSize(arr, a, b);     cout << res;     return 0; } 
Java
// Java program to find the length of the longest subset // using memoization  import java.util.*;  class GfG {     static int findMaxSubsetSize(int index, int n,                              int[] zeroCounts,                              String[] strs, int maxZeros,                              int maxOnes, int[][][] memo) {          // Base case: if we've processed all strings, return         // 0         if (index >= n)             return 0;          // Memoization check: if this state has already been         // computed, return its stored result         if (memo[index][maxZeros][maxOnes] != -1)             return memo[index][maxZeros][maxOnes];          // Option 1: Skip the current string         int maxSubset             = findMaxSubsetSize(index + 1, n, zeroCounts, strs,                             maxZeros, maxOnes, memo);          int zeroCount = zeroCounts[index];         int oneCount = strs[index].length() - zeroCount;          // Option 2: Include the current string if it         // doesn't exceed the max zeros and ones allowed         if (zeroCount <= maxZeros && oneCount <= maxOnes) {             int includeCurrent                 = 1                   + findMaxSubsetSize(index + 1, n, zeroCounts,                                   strs,                                   maxZeros - zeroCount,                                   maxOnes - oneCount, memo);             maxSubset = Math.max(maxSubset, includeCurrent);         }          // Memoize the result for the current state and         // return it         memo[index][maxZeros][maxOnes] = maxSubset;         return maxSubset;     }      static int maxSubsetSize(String[] strs, int maxZeros,                            int maxOnes) {         int n = strs.length;          // 3D DP array to memoize results, initialized to -1         // for uncomputed states         int[][][] memo             = new int[n + 1][maxZeros + 1][maxOnes + 1];         for (int i = 0; i <= n; i++) {             for (int j = 0; j <= maxZeros; j++) {                 Arrays.fill(memo[i][j], -1);             }         }          // Precompute the count of zeros in each string and         // store in zeroCounts array         int[] zeroCounts = new int[n];         for (int i = 0; i < n; i++) {             int countZeros = 0;             for (char c : strs[i].toCharArray()) {                 if (c == '0')                     countZeros++;             }             zeroCounts[i] = countZeros;         }          // Start the recursive helper function from the         // first string         return findMaxSubsetSize(0, n, zeroCounts, strs,                              maxZeros, maxOnes, memo);     }      public static void main(String[] args) {          String[] arr = { "1", "0", "0001", "10", "111001" };         int a = 5, b = 3;         int res = maxSubsetSize(arr, a, b);         System.out.println(res);     } } 
Python
# Python program to find the length of the longest subset # using memoization  from typing import List   def findMaxSubsetSize(index: int, n: int, zeroCounts: \                       List[int], strs: List[str], maxZeros: int,\                       maxOnes: int, memo: List[List[List[int]]]) -> int:        # Base case: if we've processed all strings, return 0     if index >= n:         return 0      # Memoization check: if this state has      # already been computed, return its stored result     if memo[index][maxZeros][maxOnes] != -1:         return memo[index][maxZeros][maxOnes]      # Option 1: Skip the current string     maxSubset = findMaxSubsetSize(index + 1, n, zeroCounts,                               strs, maxZeros, maxOnes, memo)      zeroCount = zeroCounts[index]     oneCount = len(strs[index]) - zeroCount      # Option 2: Include the current string if it doesn't      # exceed the max zeros and ones allowed     if zeroCount <= maxZeros and oneCount <= maxOnes:         includeCurrent = 1 + \             findMaxSubsetSize(index + 1, n, zeroCounts, strs,                           maxZeros - zeroCount, maxOnes - oneCount, memo)         maxSubset = max(maxSubset, includeCurrent)      # Memoize the result for the current state and return it     memo[index][maxZeros][maxOnes] = maxSubset     return maxSubset   def maxSubsetSize(strs: List[str], maxZeros: int, maxOnes: int) -> int:     n = len(strs)      # 3D DP array to memoize results,      # initialized to -1 for uncomputed states     memo = [[[-1] * (maxOnes + 1) for _ in range(maxZeros + 1)]           for _ in range(n + 1)]      # Precompute the count of zeros in each      # string and store in zeroCounts array     zeroCounts = [s.count('0') for s in strs]      # Start the recursive helper function      # from the first string     return findMaxSubsetSize(0, n, zeroCounts, strs, maxZeros, maxOnes, memo)   arr = ["1", "0", "0001", "10", "111001"] a, b = 5, 3 res = maxSubsetSize(arr, a, b); print(res) 
C#
// C# program to find the length of the longest subset // using memoization  using System;  class GfG {     static int findMaxSubsetSize(int index, int n,                              int[] zeroCounts,                              string[] strs, int maxZeros,                              int maxOnes, int[, , ] memo) {                // Base case: if we've processed all strings, return         // 0         if (index >= n)             return 0;          // Memoization check: if this state has already been         // computed, return its stored result         if (memo[index, maxZeros, maxOnes] != -1)             return memo[index, maxZeros, maxOnes];          // Option 1: Skip the current string         int maxSubset             = findMaxSubsetSize(index + 1, n, zeroCounts, strs,                             maxZeros, maxOnes, memo);          int zeroCount = zeroCounts[index];         int oneCount = strs[index].Length - zeroCount;          // Option 2: Include the current string if it         // doesn't exceed the max zeros and ones allowed         if (zeroCount <= maxZeros && oneCount <= maxOnes) {             int includeCurrent                 = 1                   + findMaxSubsetSize(index + 1, n, zeroCounts,                                   strs,                                   maxZeros - zeroCount,                                   maxOnes - oneCount, memo);             maxSubset = Math.Max(maxSubset, includeCurrent);         }          // Memoize the result for the current state and         // return it         memo[index, maxZeros, maxOnes] = maxSubset;         return maxSubset;     }      static int maxSubsetSize(string[] strs, int maxZeros,                            int maxOnes) {         int n = strs.Length;          // 3D DP array to memoize results, initialized to -1         // for uncomputed states         int[, , ] memo             = new int[n + 1, maxZeros + 1, maxOnes + 1];         for (int i = 0; i <= n; i++)             for (int j = 0; j <= maxZeros; j++)                 for (int k = 0; k <= maxOnes; k++)                     memo[i, j, k] = -1;          // Precompute the count of zeros in each string and         // store in zeroCounts array         int[] zeroCounts = new int[n];         for (int i = 0; i < n; i++) {             int countZeros = 0;             foreach(char c in strs[i]) {                 if (c == '0')                     countZeros++;             }             zeroCounts[i] = countZeros;         }          // Start the recursive helper function from the         // first string         return findMaxSubsetSize(0, n, zeroCounts, strs,                              maxZeros, maxOnes, memo);     }      public static void Main() {         string[] arr = { "1", "0", "0001", "10", "111001" };         int a = 5, b = 3;         int res = maxSubsetSize(arr, a, b);         Console.WriteLine(res);     } } 
JavaScript
// JavaScript program to find the length of the longest // subset using memoization  function findMaxSubsetSize(index, n, zeroCounts, strs, maxZeros,                        maxOnes, memo) {      // Base case: if we've processed all strings, return 0     if (index >= n) {         return 0;     }      // Memoization check: if this state has already been     // computed, return its stored result     if (memo[index][maxZeros][maxOnes] !== -1) {         return memo[index][maxZeros][maxOnes];     }      // Option 1: Skip the current string     let maxSubset         = findMaxSubsetSize(index + 1, n, zeroCounts, strs,                         maxZeros, maxOnes, memo);      let zeroCount = zeroCounts[index];     let oneCount = strs[index].length - zeroCount;      // Option 2: Include the current string if it doesn't     // exceed the max zeros and ones allowed     if (zeroCount <= maxZeros && oneCount <= maxOnes) {         let includeCurrent             = 1               + findMaxSubsetSize(index + 1, n, zeroCounts,                               strs, maxZeros - zeroCount,                               maxOnes - oneCount, memo);         maxSubset = Math.max(maxSubset, includeCurrent);     }      // Memoize the result for the current state and return     // it     memo[index][maxZeros][maxOnes] = maxSubset;     return maxSubset; }  function maxSubsetSize(strs, maxZeros, maxOnes) {     const n = strs.length;      // 3D DP array to memoize results, initialized to -1 for     // uncomputed states     const memo = Array.from(         {length : n + 1},         () => Array.from(             {length : maxZeros + 1},             () => Array(maxOnes + 1).fill(-1)));      // Precompute the count of zeros in each string and     // store in zeroCounts array     const zeroCounts         = strs.map(str => str.split("0").length - 1);      // Start the recursive helper function from the first     // string     return findMaxSubsetSize(0, n, zeroCounts, strs, maxZeros,                          maxOnes, memo); }  const arr = [ "1", "0", "0001", "10", "111001" ]; const a = 5, b = 3; const res = maxSubsetSize(arr, a, b); console.log(res); 

Output
4

Using Bottom-Up DP (Tabulation) - O(n*a*b) Time and O(n*a*b) Space

The approach is similar to the previous one. just instead of breaking down the problem recursively, we iteratively build up the solution by calculating in bottom-up manner where dp[i][j][k] represent the maximum size of the subset of the first i strings that can be formed using at most j zeros and k ones.

Base Case:

if i = 0, j = 0, k = 0
dp[i][j][k] = 0

Recurrance relations:

if zeros[i-1] > j or ones[i-1] > k
dp[i][j][k] = dp[i-1][j][k]

else
dp[i][j][k] = max(dp[i-1][j][k], 1 + dp[i-1][j-zeros[i-1]][k-ones[i-1]]) here, zeros[i-1] and ones[i-1] is the number of zeros and ones, respectively, in the (i-1)th string.

C++
// C++ program to find the length of the longest subset // using tabulation  #include <algorithm> #include <iostream> #include <vector> using namespace std;  int maxSubsetSize(vector<string> &strs, int maxZeros, int maxOnes) {     int n = strs.size();      // 3D DP array to store results     vector<vector<vector<int>>> dp(n + 1, vector<vector<int>> 	(maxZeros + 1, vector<int>(maxOnes + 1, 0)));      // Precompute the count of zeros in each string     // and store in zeroCounts array     vector<int> zeroCounts(n, 0);     for (int i = 0; i < n; i++) {         int countZeros = 0;         for (char c : strs[i]) {             if (c == '0')                 countZeros++;         }         zeroCounts[i] = countZeros;     }      // Fill the DP table     for (int i = 1; i <= n; i++) {         for (int j = 0; j <= maxZeros; j++) {             for (int k = 0; k <= maxOnes; k++) {                                // Option 1: Don't include the current string                 dp[i][j][k] = dp[i - 1][j][k];                  // Option 2: Include the current string if it doesn't exceed                 // the max zeros and ones                 int zeroCount = zeroCounts[i - 1];                 int oneCount = strs[i - 1].size() - zeroCount;                  if (zeroCount <= j && oneCount <= k) {                     dp[i][j][k] = max(dp[i][j][k], 1 + dp[i - 1][j - zeroCount][k - oneCount]);                 }             }         }     }      // Return the result from the DP table     return dp[n][maxZeros][maxOnes]; }  int main() {     vector<string> arr = {"1", "0", "0001", "10", "111001"};     int a = 5, b = 3;     int res = maxSubsetSize(arr, a, b);     cout << res;     return 0; } 
Java
// Java program to find the length of the longest subset // using Tabulation  import java.util.*;  class GfG {        static int maxSubsetSize(List<String> strs,                                     int maxZeros,                                     int maxOnes) {         int n = strs.size();          // 3D DP array to store results         int[][][] dp             = new int[n + 1][maxZeros + 1][maxOnes + 1];          // Precompute the count of zeros in each string and         // store in zeroCounts array         int[] zeroCounts = new int[n];         for (int i = 0; i < n; i++) {             int countZeros = 0;             for (char c : strs.get(i).toCharArray()) {                 if (c == '0')                     countZeros++;             }             zeroCounts[i] = countZeros;         }          // Fill the DP table         for (int i = 1; i <= n; i++) {             for (int j = 0; j <= maxZeros; j++) {                 for (int k = 0; k <= maxOnes; k++) {                                        // Option 1: Don't include the current                     // string                     dp[i][j][k] = dp[i - 1][j][k];                      // Option 2: Include the current string                     // if it doesn't exceed the max zeros                     // and ones                     int zeroCount = zeroCounts[i - 1];                     int oneCount = strs.get(i - 1).length()                                    - zeroCount;                      if (zeroCount <= j && oneCount <= k) {                         dp[i][j][k] = Math.max(                             dp[i][j][k],                             1                                 + dp[i - 1][j - zeroCount]                                     [k - oneCount]);                     }                 }             }         }          // Return the result from the DP table         return dp[n][maxZeros][maxOnes];     }      public static void main(String[] args) {         List<String> arr = Arrays.asList("1", "0", "0001",                                          "10", "111001");         int a = 5, b = 3;         int res = maxSubsetSize(arr, a, b);         System.out.println(res);     } } 
Python
# Python program to find the length of the longest subset # using Tabulation   def maxSubsetSize(strs, maxZeros, maxOnes):     n = len(strs)      # 3D DP array to store results     dp = [[[0] * (maxOnes + 1) for _ in range(maxZeros + 1)]           for _ in range(n + 1)]      # Precompute the count of zeros in each     # string and store in zeroCounts array     zeroCounts = [0] * n     for i in range(n):         countZeros = strs[i].count('0')         zeroCounts[i] = countZeros      # Fill the DP table     for i in range(1, n + 1):         for j in range(maxZeros + 1):             for k in range(maxOnes + 1):                                # Option 1: Don't include the current string                 dp[i][j][k] = dp[i - 1][j][k]                  # Option 2: Include the current string if                 # it doesn't exceed the max zeros and ones                 zeroCount = zeroCounts[i - 1]                 oneCount = len(strs[i - 1]) - zeroCount                  if zeroCount <= j and oneCount <= k:                     dp[i][j][k] = max(dp[i][j][k], 1 + dp[i - 1]                                       [j - zeroCount][k - oneCount])      # Return the result from the DP table     return dp[n][maxZeros][maxOnes]   if __name__ == "__main__":     arr = ["1", "0", "0001", "10", "111001"]     a, b = 5, 3     res = maxSubsetSize(arr, a, b)     print(res) 
C#
// C# program to find the length of the longest subset // using Tabulation using System; using System.Linq;  class GfG {        // Function to calculate the maximum subset size     static int maxSubsetSize(string[] strs, int maxZeros, int maxOnes) {                int n = strs.Length;          // 3D DP array to store the results         int[, ,] dp = new int[n + 1, maxZeros + 1, maxOnes + 1];          // Precompute the count of zeros in each        	// string and store in zeroCounts array         int[] zeroCounts = new int[n];         for (int i = 0; i < n; i++) {             zeroCounts[i] = strs[i].Count(c => c == '0');         }          // Fill the DP table         for (int i = 1; i <= n; i++) {             for (int j = 0; j <= maxZeros; j++) {                 for (int k = 0; k <= maxOnes; k++) {                                        // Option 1: Don't include the current string                     dp[i, j, k] = dp[i - 1, j, k];                      // Option 2: Include the current string if                   	// it doesn't exceed the max zeros and ones                     int zeroCount = zeroCounts[i - 1];                     int oneCount = strs[i - 1].Length - zeroCount;                      if (zeroCount <= j && oneCount <= k) {                         dp[i, j, k] = Math.Max(dp[i, j, k],                             1 + dp[i - 1, j - zeroCount, k - oneCount]);                     }                 }             }         }          // Return the result from the DP table (maximum subset size)         return dp[n, maxZeros, maxOnes];     }      static void Main() {              string[] arr = { "1", "0", "0001", "10", "111001" };          int a = 5, b = 3;         int res = maxSubsetSize(arr, a, b);         Console.WriteLine(res);       } } 
JavaScript
// JavaScript program to find the length of the longest // subset using Tabulation  function maxSubsetSize(strs, maxZeros, maxOnes) {      const n = strs.length;      // 3D DP array to store results     const dp = Array.from(         {length : n + 1},         () => Array.from({length : maxZeros + 1},                          () => Array(maxOnes + 1).fill(0)));      // Precompute the count of zeros in each string and     // store in zeroCounts array     const zeroCounts = strs.map(         str => str.split("").filter(c => c === "0").length);      // Fill the DP table     for (let i = 1; i <= n; i++) {         for (let j = 0; j <= maxZeros; j++) {             for (let k = 0; k <= maxOnes; k++) {                  // Option 1: Don't include the current                 // string                 dp[i][j][k] = dp[i - 1][j][k];                  // Option 2: Include the current string if                 // it doesn't exceed the max zeros and ones                 const zeroCount = zeroCounts[i - 1];                 const oneCount                     = strs[i - 1].length - zeroCount;                  if (zeroCount <= j && oneCount <= k) {                     dp[i][j][k] = Math.max(                         dp[i][j][k],                         1                             + dp[i - 1][j - zeroCount]                                 [k - oneCount]);                 }             }         }     }     return dp[n][maxZeros][maxOnes]; }  const arr = [ "1", "0", "0001", "10", "111001" ]; const a = 5, b = 3; const res = maxSubsetSize(arr, a, b); console.log(res); 

Output
4



Next Article
Coin Change - Minimum Coins to Make Sum

S

sukritidawar
Improve
Article Tags :
  • Strings
  • Dynamic Programming
  • Mathematical
  • Competitive Programming
  • Recursion
  • C++ Programs
  • C++
  • DSA
  • Arrays
  • subset
  • Memoization
Practice Tags :
  • CPP
  • Arrays
  • Dynamic Programming
  • Mathematical
  • Recursion
  • Strings
  • subset

Similar Reads

    Introduction to Knapsack Problem, its Types and How to solve them
    The Knapsack problem is an example of the combinational optimization problem. This problem is also commonly known as the "Rucksack Problem". The name of the problem is defined from the maximization problem as mentioned below:Given a bag with maximum weight capacity of W and a set of items, each havi
    6 min read

    Fractional Knapsack

    Fractional Knapsack Problem
    Given two arrays, val[] and wt[], representing the values and weights of items, and an integer capacity representing the maximum weight a knapsack can hold, the task is to determine the maximum total value that can be achieved by putting items in the knapsack. You are allowed to break items into fra
    8 min read
    Fractional Knapsack Queries
    Given an integer array, consisting of positive weights "W" and their values "V" respectively as a pair and some queries consisting of an integer 'C' specifying the capacity of the knapsack, find the maximum value of products that can be put in the knapsack if the breaking of items is allowed. Exampl
    9 min read
    Difference between 0/1 Knapsack problem and Fractional Knapsack problem
    What is Knapsack Problem?Suppose you have been given a knapsack or bag with a limited weight capacity, and each item has some weight and value. The problem here is that "Which item is to be placed in the knapsack such that the weight limit does not exceed and the total value of the items is as large
    13 min read

    0/1 Knapsack

    0/1 Knapsack Problem
    Given n items where each item has some weight and profit associated with it and also given a bag with capacity W, [i.e., the bag can hold at most W weight in it]. The task is to put the items into the bag such that the sum of profits associated with them is the maximum possible. Note: The constraint
    15+ min read
    Printing Items in 0/1 Knapsack
    Given weights and values of n items, put these items in a knapsack of capacity W to get the maximum total value in the knapsack. In other words, given two integer arrays, val[0..n-1] and wt[0..n-1] represent values and weights associated with n items respectively. Also given an integer W which repre
    12 min read
    0/1 Knapsack Problem to print all possible solutions
    Given weights and profits of N items, put these items in a knapsack of capacity W. The task is to print all possible solutions to the problem in such a way that there are no remaining items left whose weight is less than the remaining capacity of the knapsack. Also, compute the maximum profit.Exampl
    10 min read
    0-1 knapsack queries
    Given an integer array W[] consisting of weights of the items and some queries consisting of capacity C of knapsack, for each query find maximum weight we can put in the knapsack. Value of C doesn't exceed a certain integer C_MAX. Examples: Input: W[] = {3, 8, 9} q = {11, 10, 4} Output: 11 9 3 If C
    12 min read
    0/1 Knapsack using Branch and Bound
    Given two arrays v[] and w[] that represent values and weights associated with n items respectively. Find out the maximum value subset(Maximum Profit) of v[] such that the sum of the weights of this subset is smaller than or equal to Knapsack capacity W.Note: The constraint here is we can either put
    15+ min read
    0/1 Knapsack using Least Cost Branch and Bound
    Given N items with weights W[0..n-1], values V[0..n-1] and a knapsack with capacity C, select the items such that:   The sum of weights taken into the knapsack is less than or equal to C.The sum of values of the items in the knapsack is maximum among all the possible combinations.Examples:   Input:
    15+ min read
    Unbounded Fractional Knapsack
    Given the weights and values of n items, the task is to put these items in a knapsack of capacity W to get the maximum total value in the knapsack, we can repeatedly put the same item and we can also put a fraction of an item. Examples: Input: val[] = {14, 27, 44, 19}, wt[] = {6, 7, 9, 8}, W = 50 Ou
    5 min read
    Unbounded Knapsack (Repetition of items allowed)
    Given a knapsack weight, say capacity and a set of n items with certain value vali and weight wti, The task is to fill the knapsack in such a way that we can get the maximum profit. This is different from the classical Knapsack problem, here we are allowed to use an unlimited number of instances of
    15+ min read
    Unbounded Knapsack (Repetition of items allowed) | Efficient Approach
    Given an integer W, arrays val[] and wt[], where val[i] and wt[i] are the values and weights of the ith item, the task is to calculate the maximum value that can be obtained using weights not exceeding W. Note: Each weight can be included multiple times. Examples: Input: W = 4, val[] = {6, 18}, wt[]
    8 min read
    Double Knapsack | Dynamic Programming
    Given an array arr[] containing the weight of 'n' distinct items, and two knapsacks that can withstand capactiy1 and capacity2 weights, the task is to find the sum of the largest subset of the array 'arr', that can be fit in the two knapsacks. It's not allowed to break any items in two, i.e. an item
    15+ min read

    Some Problems of Knapsack problem

    Partition a Set into Two Subsets of Equal Sum
    Given an array arr[], the task is to check if it can be partitioned into two parts such that the sum of elements in both parts is the same.Note: Each element is present in either the first subset or the second subset, but not in both.Examples: Input: arr[] = [1, 5, 11, 5]Output: true Explanation: Th
    15+ min read
    Count of subsets with sum equal to target
    Given an array arr[] of length n and an integer target, the task is to find the number of subsets with a sum equal to target.Examples: Input: arr[] = [1, 2, 3, 3], target = 6 Output: 3 Explanation: All the possible subsets are [1, 2, 3], [1, 2, 3] and [3, 3]Input: arr[] = [1, 1, 1, 1], target = 1 Ou
    15+ min read
    Length of longest subset consisting of A 0s and B 1s from an array of strings
    Given an array arr[] consisting of binary strings, and two integers a and b, the task is to find the length of the longest subset consisting of at most a 0s and b 1s.Examples:Input: arr[] = ["1" ,"0" ,"0001" ,"10" ,"111001"], a = 5, b = 3Output: 4Explanation: One possible way is to select the subset
    15+ min read
    Breaking an Integer to get Maximum Product
    Given a number n, the task is to break n in such a way that multiplication of its parts is maximized. Input : n = 10Output: 36Explanation: 10 = 4 + 3 + 3 and 4 * 3 * 3 = 36 is the maximum possible product. Input: n = 8Output: 18Explanation: 8 = 2 + 3 + 3 and 2 * 3 * 3 = 18 is the maximum possible pr
    15+ min read
    Coin Change - Minimum Coins to Make Sum
    Given an array of coins[] of size n and a target value sum, where coins[i] represent the coins of different denominations. You have an infinite supply of each of the coins. The task is to find the minimum number of coins required to make the given value sum. If it is not possible to form the sum usi
    15+ min read
    Coin Change - Count Ways to Make Sum
    Given an integer array of coins[] of size n representing different types of denominations and an integer sum, the task is to count all combinations of coins to make a given value sum. Note: Assume that you have an infinite supply of each type of coin. Examples: Input: sum = 4, coins[] = [1, 2, 3]Out
    15+ min read
    Maximum sum of values of N items in 0-1 Knapsack by reducing weight of at most K items in half
    Given weights and values of N items and the capacity W of the knapsack. Also given that the weight of at most K items can be changed to half of its original weight. The task is to find the maximum sum of values of N items that can be obtained such that the sum of weights of items in knapsack does no
    15+ min read
geeksforgeeks-footer-logo
Corporate & Communications Address:
A-143, 7th Floor, Sovereign Corporate Tower, Sector- 136, Noida, Uttar Pradesh (201305)
Registered Address:
K 061, Tower K, Gulshan Vivante Apartment, Sector 137, Noida, Gautam Buddh Nagar, Uttar Pradesh, 201305
GFG App on Play Store GFG App on App Store
Advertise with us
  • Company
  • About Us
  • Legal
  • Privacy Policy
  • In Media
  • Contact Us
  • Advertise with us
  • GFG Corporate Solution
  • Placement Training Program
  • Languages
  • Python
  • Java
  • C++
  • PHP
  • GoLang
  • SQL
  • R Language
  • Android Tutorial
  • Tutorials Archive
  • DSA
  • Data Structures
  • Algorithms
  • DSA for Beginners
  • Basic DSA Problems
  • DSA Roadmap
  • Top 100 DSA Interview Problems
  • DSA Roadmap by Sandeep Jain
  • All Cheat Sheets
  • Data Science & ML
  • Data Science With Python
  • Data Science For Beginner
  • Machine Learning
  • ML Maths
  • Data Visualisation
  • Pandas
  • NumPy
  • NLP
  • Deep Learning
  • Web Technologies
  • HTML
  • CSS
  • JavaScript
  • TypeScript
  • ReactJS
  • NextJS
  • Bootstrap
  • Web Design
  • Python Tutorial
  • Python Programming Examples
  • Python Projects
  • Python Tkinter
  • Python Web Scraping
  • OpenCV Tutorial
  • Python Interview Question
  • Django
  • Computer Science
  • Operating Systems
  • Computer Network
  • Database Management System
  • Software Engineering
  • Digital Logic Design
  • Engineering Maths
  • Software Development
  • Software Testing
  • DevOps
  • Git
  • Linux
  • AWS
  • Docker
  • Kubernetes
  • Azure
  • GCP
  • DevOps Roadmap
  • System Design
  • High Level Design
  • Low Level Design
  • UML Diagrams
  • Interview Guide
  • Design Patterns
  • OOAD
  • System Design Bootcamp
  • Interview Questions
  • Inteview Preparation
  • Competitive Programming
  • Top DS or Algo for CP
  • Company-Wise Recruitment Process
  • Company-Wise Preparation
  • Aptitude Preparation
  • Puzzles
  • School Subjects
  • Mathematics
  • Physics
  • Chemistry
  • Biology
  • Social Science
  • English Grammar
  • Commerce
  • World GK
  • GeeksforGeeks Videos
  • DSA
  • Python
  • Java
  • C++
  • Web Development
  • Data Science
  • CS Subjects
@GeeksforGeeks, Sanchhaya Education Private Limited, All rights reserved
We use cookies to ensure you have the best browsing experience on our website. By using our site, you acknowledge that you have read and understood our Cookie Policy & Privacy Policy
Lightbox
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
geeksforgeeks-suggest-icon
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.
geeksforgeeks-improvement-icon
Suggest Changes
min 4 words, max Words Limit:1000

Thank You!

Your suggestions are valuable to us.

What kind of Experience do you want to share?

Interview Experiences
Admission Experiences
Career Journeys
Work Experiences
Campus Experiences
Competitive Exam Experiences