Open In App

Maximum number of strings that can be formed with given zeros and ones

Improve
Improve
Like Article
Like
Save
Share
Report

Given a list of strings arr[] of zeros and ones only and two integer N and M, where N is the number of 1’s and M is the number of 0’s. The task is to find the maximum number of strings from the given list of strings that can be constructed with given number of 0’s and 1’s.

Examples: 

Input: arr[] = {“10”, “0001”, “11100”, “1”, “0”}, M = 5, N = 3 
Output:
Explanation: 
The 4 strings which can be formed using five 0’s and three 1’s are: “10”, “0001”, “1”, “0”

Input: arr[] = {“10”, “00”, “000”, “0001”, “111001”, “1”, “0”}, M = 3, N = 1 
Output:
Explanation: 
The 3 strings which can be formed using three 0’s and one 1’s are: “00”, “1”, “0” 
 

Naive Approach: The idea is to generate all the combinations of the given list of strings and check the count of zeros and ones satisfying the given condition. But the time complexity of this solution is exponential. 

 Intuition:

The first thing that we will see is that

  • From the given array of strings, we have to choose some of its indices, such that after choosing them we will count our ones and zeros.
  • So, this is a kind of option type thing, suppose we start traversing in our given vector and stand on any ith index, then for that index we have a choice.
  • And what choice is that? The choice is that we will ask ourselves whether to include this string in our answer or not.
  • So, if we decide to choose this string in our answer then we will add the count of ones and zeroes of this string in our answer and move ahead and if we decide not to include this string in our answer, then we will do nothing, we just move forward.
  • So, Overall we can say that we have a choice for every index of array whether to include our answer or not to include.
  • And whenever we heard a term that here we have a choice like this, then we will say recursion will use here.
  • Why recursion? Recursion is because it will try out every single possibility for every string in our answer.

C++




// C++ program for the above Naive approach
#include <bits/stdc++.h>
using namespace std;
 // Count one and Zero function take string as parameter and count the number of ones and zeroes present in the string and return the counts.
    pair<int, int> countOneAndZero(string s)
    {
        int one = 0, zero = 0;
         
        for(int i = 0; i < s.length(); i++) // travel in the string
        {
            if(s[i] == '1'// if == '1', then add to one
                one++;
            else            // otherwise add to zero
                zero++;
        }
         
        return {one, zero};
    }
int countString(int i, int one, int zero, int& maxZero, int& maxOne,
             vector<string>& arr)
    {
        if(i >= arr.size()) // if ith index crosses the length then return 0
            return 0;
         
        // if any of the count, crosses the criteria of having maximum one
        // or zero, then return 0
        if(one > maxOne || zero > maxZero)
            return 0;
         
        /* what we discussed:-
        for every ith index i, we have two option, whether to include it
         in our answer or not, if include then add the count of
         ones and zeros from that string */
         
        // pair p contains, the number of ones and zeroes present in the string of ith index of vector arr.
        pair<int, int> p = countOneAndZero(arr[i]);
         
        /* we declare three variables -
        1) ans1, If adding the count of ones and zeroes at ith index in arr,
        does not crosses our limit, then to include this in our answer.
        2) ans2, If adding the count of ones and zeroes at ith index in arr,
        does not crosses our limit, then not to include this in our answer.
        3) ansWithout, If adding the count of ones and zeroes at ith index in arr, crosses our limit, then not to include this in our answer.
        */
         
        int ans1 = 0, ans2 = 0, ansWithout = 0;
         
        // adding count of current index, not to cross our limit then-
        if(one + p.first <= maxOne && zero + p.second <= maxZero)
        {
            // ans1, including it in our answer
            ans1 = 1 + countString(i + 1, one + p.first, zero + p.second,
                           maxZero, maxOne, arr);
             
            // not including in our answer.
            ans2 = countString(i + 1, one, zero, maxZero, maxOne, arr);
        }
        else // if crossing limit, obviously not to take
        {
            ansWithout = countString(i + 1, one, zero, maxZero, maxOne, arr);
        }
         
        // and at last return the maximum of them
        return max({ans1, ans2, ansWithout});
         
         
    }
                 
int main() {
 
    vector<string> arr = { "10", "0001", "1",
                           "111001", "0" };
  
    // N 0's and M 1's
    int N = 3, M = 5;
    
    int idx=0;
    int one=0;
    int zero=0;
    // Function call
    cout << countString(idx,one,zero,M, N, arr);
}
 
//This code is Contributed by Suchi


Java




// Java program for above approach
import java.util.*;
 
public class GFG {
  static class pair {
    int first, second;
    pair(int first, int second)
    {
      this.first = first;
      this.second = second;
    }
  }
 
  // Count one and Zero function take string as parameter
  // and count the number of ones and zeroes present in
  // the string and return the counts.
  static pair countOneAndZero(String s)
  {
    int one = 0, zero = 0;
 
    for (int i = 0; i < s.length();
         i++) // travel in the string
    {
      if (s.charAt(i)
          == '1') // if == '1', then add to one
        one++;
      else // otherwise add to zero
        zero++;
    }
 
    return new pair(one, zero);
  }
  static int countString(int i, int one, int zero,
                         int maxZero, int maxOne,
                         String[] arr)
  {
    if (i >= arr.length) // if ith index crosses the
      // length then return 0
      return 0;
 
    // if any of the count, crosses the criteria of
    // having maximum one or zero, then return 0
    if (one > maxOne || zero > maxZero)
      return 0;
 
    /* what we discussed:-
        for every ith index i, we have two option, whether
        to include it in our answer or not, if include then
        add the count of ones and zeros from that string */
 
    // pair p contains, the number of ones and zeroes
    // present in the string of ith index of vector arr.
    pair p = countOneAndZero(arr[i]);
 
    /* we declare three variables -
        1) ans1, If adding the count of ones and zeroes at
        ith index in arr, does not crosses our limit, then
        to include this in our answer. 2) ans2, If adding
        the count of ones and zeroes at ith index in arr,
        does not crosses our limit, then not to include this
        in our answer. 3) ansWithout, If adding the count of
        ones and zeroes at ith index in arr, crosses our
        limit, then not to include this in our answer.
        */
 
    int ans1 = 0, ans2 = 0, ansWithout = 0;
 
    // adding count of current index, not to cross our
    // limit then-
    if (one + p.first <= maxOne
        && zero + p.second <= maxZero) {
      // ans1, including it in our answer
      ans1 = 1
        + countString(i + 1, one + p.first,
                      zero + p.second, maxZero,
                      maxOne, arr);
 
      // not including in our answer.
      ans2 = countString(i + 1, one, zero, maxZero,
                         maxOne, arr);
    }
    else // if crossing limit, obviously not to take
    {
      ansWithout = countString(i + 1, one, zero,
                               maxZero, maxOne, arr);
    }
 
    // and at last return the maximum of them
    return Math.max(ans1, Math.max(ans2, ansWithout));
  }
  public static void main(String[] args)
  {
    String[] arr = { "10", "0001", "1", "111001", "0" };
 
    // N 0's and M 1's
    int N = 3, M = 5;
 
    int idx = 0;
    int one = 0;
    int zero = 0;
    // Function call
    System.out.println(
      countString(idx, one, zero, M, N, arr));
  }
}
 
// This code is contributed by karandeep1234


Python3




# Python code for the above approach
 
# Count one and Zero function take string as parameter
# and count the number of ones and zeroes present in
# the string and return the counts.
def countOneAndZero(s):
    one, zero = 0, 0
    for i in range(len(s)):
        # if i=='1', then add to one
        if(s[i] == '1'):
            one += 1
        # otherwise add to zero
        else:
            zero += 1
 
    return [one, zero]
 
def countString(i, one, zero, maxZero, maxOne, arr):
    # If ith index crosses the length then return 0
    if(i >= len(arr)):
        return 0
    # if any of the count, crosses the criteria of
    # having maximum one or zero, then return 0
    if(one > maxOne or zero > maxZero):
        return 0
 
    # what we discussed:-
       # for every ith index i, we have two option, whether
       # to include it in our answer or not, if include then
       # add the count of ones and zeros from that string
 
    # pair p contains, the number of ones and zeroes
    # present in the string of ith index of vector arr.
    p = countOneAndZero(arr[i])
 
    # we declare three variables -
    # 1) ans1, If adding the count of ones and zeroes at
    # ith index in arr, does not crosses our limit, then
    # to include this in our answer.
    # 2) ans2, If adding the count of ones and zeroes at ith
    # index in arr, does not crosses our limit, then not to
    # include this in our answer.
    # 3) ansWithout, If adding the count of
    # ones and zeroes at ith index in arr, crosses our
    # limit, then not to include this in our answer.
 
    ans1, ans2, ansWithout = 0, 0, 0
 
    # adding count of current index, not to cross our limit then-
    if(one + p[0] <= maxOne and zero + p[1] <= maxZero):
        # ans1, including it in our answer
        ans1 = 1 + countString(i+1, one +
                               p[0], zero + p[1], maxZero, maxOne, arr)
        # not including in our answer
        ans2 = countString(i+1, one, zero, maxZero, maxOne, arr)
 
    # if crossing limit, obviously not to take
    else:
        ansWithout = countString(i+1, one, zero, maxZero, maxOne, arr)
 
    # and at last return the maximum of them
    return max(ans1, max(ans2, ansWithout))
 
 
arr = ["10", "0001", "1", "111001", "0"]
# N 0's and M 1's
N, M = 3, 5
idx, one, zero = 0, 0, 0
# Function call
print(countString(idx, one, zero, M, N, arr))
 
# This code is contributed by lokeshmvs21.


C#




using System;
class GFG
{
 
  // Count one and Zero function take string as parameter
  // and count the number of ones and zeroes present in
  // the string and return the counts.
  static int[] countOneAndZero(String s)
  {
    int one = 0, zero = 0;
 
    for (int i = 0; i < s.Length;
         i++) // travel in the string
    {
      if (s[i] == '1') // if == '1', then add to one
        one++;
      else // otherwise add to zero
        zero++;
    }
    int[] p = { one, zero };
    return p;
  }
  static int countString(int i, int one, int zero,
                         int maxZero, int maxOne,
                         String[] arr)
  {
    if (i >= arr.Length) // if ith index crosses the
      // length then return 0
      return 0;
 
    // if any of the count, crosses the criteria of
    // having maximum one or zero, then return 0
    if (one > maxOne || zero > maxZero)
      return 0;
 
    /* what we discussed:-
            for every ith index i, we have two option,
           whether to include it in our answer or not, if
           include then
            add the count of ones and zeros from that string
         */
 
    // pair p contains, the number of ones and zeroes
    // present in the string of ith index of vector arr.
    int[] p = countOneAndZero(arr[i]);
 
    /* we declare three variables -
            1) ans1, If adding the count of ones and zeroes
           at ith index in arr, does not crosses our limit,
           then to include this in our answer. 2) ans2, If
           adding the count of ones and zeroes at ith index
           in arr, does not crosses our limit, then not to
           include this in our answer. 3) ansWithout, If
           adding the count of ones and zeroes at ith index
           in arr, crosses our limit, then not to include
           this in our answer.
            */
 
    int ans1 = 0, ans2 = 0, ansWithout = 0;
 
    // adding count of current index, not to cross our
    // limit then-
    if (one + p[0] <= maxOne
        && zero + p[1] <= maxZero) {
      // ans1, including it in our answer
      ans1 = 1
        + countString(i + 1, one + p[0],
                      zero + p[1], maxZero,
                      maxOne, arr);
 
      // not including in our answer.
      ans2 = countString(i + 1, one, zero, maxZero,
                         maxOne, arr);
    }
    else // if crossing limit, obviously not to take
    {
      ansWithout = countString(i + 1, one, zero,
                               maxZero, maxOne, arr);
    }
 
    // and at last return the maximum of them
    return Math.Max(ans1, Math.Max(ans2, ansWithout));
  }
  static void Main()
  {
    String[] arr = { "10", "0001", "1", "111001", "0" };
 
    // N 0's and M 1's
    int N = 3, M = 5;
 
    int idx = 0;
    int one = 0;
    int zero = 0;
 
    // Function call
    Console.Write(
      countString(idx, one, zero, M, N, arr));
  }
}
 
// This code is contributed by garg28harsh.


Javascript




// Count one and Zero function take string as
 // parameter and count the number of ones and
 // zeroes present in the string and return the counts.
    function countOneAndZero(s)
    {
        let one = 0, zero = 0;
         
        for(let i = 0; i < s.length; i++) // travel in the string
        {
            if(s[i] == '1'// if == '1', then add to one
                one++;
            else            // otherwise add to zero
                zero++;
        }
        let a=[];
        a.push(one);
        a.push(zero);
        return a;
    }
    function countString(i,  one,  zero,  maxZero,  maxOne, arr)
    {
        if(i >= arr.length) // if ith index crosses the length then return 0
            return 0;
         
        // if any of the count, crosses the criteria of having maximum one
        // or zero, then return 0
        if(one > maxOne || zero > maxZero)
            return 0;
         
        /* what we discussed:-
        for every ith index i, we have two option, whether to include it
         in our answer or not, if include then add the count of
         ones and zeros from that string */
         
        // pair p contains, the number of ones and
        // zeroes present in the string of ith index of vector arr.
        let p = countOneAndZero(arr[i]);
         
        /* we declare three variables -
        1) ans1, If adding the count of ones and zeroes at ith index in arr,
        does not crosses our limit, then to include this in our answer.
        2) ans2, If adding the count of ones and zeroes at ith index in arr,
        does not crosses our limit, then not to include this in our answer.
        3) ansWithout, If adding the count of ones and zeroes at ith index in arr, crosses our limit, then not to include this in our answer.
        */
         
        let ans1 = 0, ans2 = 0, ansWithout = 0;
         
        // adding count of current index, not to cross our limit then-
        if(one + p[0] <= maxOne && zero + p[1] <= maxZero)
        {
            // ans1, including it in our answer
            ans1 = 1 + countString(i + 1, one + p[0], zero + p[1],
                           maxZero, maxOne, arr);
             
            // not including in our answer.
            ans2 = countString(i + 1, one, zero, maxZero, maxOne, arr);
        }
        else // if crossing limit, obviously not to take
        {
            ansWithout = countString(i + 1, one, zero, maxZero, maxOne, arr);
        }
         
        // and at last return the maximum of them
        return Math.max(ansWithout,Math.max(ans1,ans2));
         
         
    }
                 
// driver code
    let arr = ["10", "0001", "1",
                           "111001", "0" ];
    // N 0's and M 1's
    let N = 3, M = 5;
    
    let idx = 0;
    let one = 0;
    let zero = 0;
     
    // Function call
    console.log(countString(idx,one,zero,M, N, arr));
     
    // This code is contributed by garg28harsh.


Time Complexity: O(2N), where N is the number of strings in the list.

Efficient Approach: 
An efficient solution is given by using Dynamic Programming. The idea is to use recursion for generating all possible combinations and store the results for Overlapping Subproblems during recursion

Below are the steps:  

  • The idea is to use 3D dp array(dp[M][N][i]) where N and M are the number of 1’s and 0’s respectively and i is the index of the string in the list.
  • Find the number of 1’s and 0’s in the current string and check if the count of the zeros and ones is less than or equals to the given count N and M respectively.
  • If above condition is true, then check whether current state value is stored in the dp table or not. If yes then return this value.
  • Else recursively move for the next iteration by including and excluding the current string as:
// By including the current string
x = 1 + recursive_function(M - zero, N - ones, arr, i + 1)

// By excluding the current string 
y = recursive_function(M, N, arr, i + 1)

// and update the dp table as:
dp[M][N][i] = max(x, y)
  • The maximum value of the above two recursive calls will give the maximum number with N 1’s and M 0’s for the current state.

Below is the implementation of the above approach:  

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// 3D dp table to store the state value
int dp[100][100][100];
 
// Function that count the combination
// of 0's and 1's from the given list
// of string
int countString(int m, int n,
                vector<string>& arr, int i)
{
    // Base Case if count of 0's or 1's
    // becomes negative
    if (m < 0 || n < 0) {
        return INT_MIN;
    }
 
    // If index reaches out of bound
    if (i >= arr.size()) {
        return 0;
    }
 
    // Return the prestored result
    if (dp[m][n][i] != -1) {
        return dp[m][n][i];
    }
 
    // Initialize count of 0's and 1's
    // to 0 for the current state
    int zero = 0, one = 0;
 
    // Calculate the number of 1's and
    // 0's in current string
    for (char c : arr[i]) {
        if (c == '0') {
            zero++;
        }
        else {
            one++;
        }
    }
 
    // Include the current string and
    // recur for the next iteration
    int x = 1 + countString(m - zero,
                            n - one,
                            arr, i + 1);
 
    // Exclude the current string and
    // recur for the next iteration
    int y = countString(m, n, arr, i + 1);
 
    // Update the maximum of the above
    // two states to the current dp state
    return dp[m][n][i] = max(x, y);
}
 
// Driver Code
int main()
{
    vector<string> arr = { "10", "0001", "1",
                           "111001", "0" };
 
    // N 0's and M 1's
    int N = 3, M = 5;
 
    // Initialize dp array to -1
    memset(dp, -1, sizeof(dp));
 
    // Function call
    cout << countString(M, N, arr, 0);
}


Java




// Java program for the above approach
class GFG{
  
// 3D dp table to store the state value
static int [][][]dp = new int[100][100][100];
  
// Function that count the combination
// of 0's and 1's from the given list
// of String
static int countString(int m, int n,
                String []arr, int i)
{
    // Base Case if count of 0's or 1's
    // becomes negative
    if (m < 0 || n < 0) {
        return Integer.MIN_VALUE;
    }
  
    // If index reaches out of bound
    if (i >= arr.length) {
        return 0;
    }
  
    // Return the prestored result
    if (dp[m][n][i] != -1) {
        return dp[m][n][i];
    }
  
    // Initialize count of 0's and 1's
    // to 0 for the current state
    int zero = 0, one = 0;
  
    // Calculate the number of 1's and
    // 0's in current String
    for (char c : arr[i].toCharArray()) {
        if (c == '0') {
            zero++;
        }
        else {
            one++;
        }
    }
  
    // Include the current String and
    // recur for the next iteration
    int x = 1 + countString(m - zero,
                            n - one,
                            arr, i + 1);
  
    // Exclude the current String and
    // recur for the next iteration
    int y = countString(m, n, arr, i + 1);
  
    // Update the maximum of the above
    // two states to the current dp state
    return dp[m][n][i] = Math.max(x, y);
}
  
// Driver Code
public static void main(String[] args)
{
    String []arr = { "10", "0001", "1",
                           "111001", "0" };
  
    // N 0's and M 1's
    int N = 3, M = 5;
  
    // Initialize dp array to -1
    for(int i = 0;i<100;i++){
        for(int j = 0;j<100;j++){
            for(int l=0;l<100;l++)
            dp[i][j][l]=-1;
        }
    }
  
    // Function call
    System.out.print(countString(M, N, arr, 0));
}
}
 
// This code is contributed by 29AjayKumar


Python3




# Python 3 program for the above approach
import sys
 
# 3D dp table to store the state value
dp = [[[-1 for i in range(100)]for j in range(100)] for k in range(100)]
 
# Function that count the combination
# of 0's and 1's from the given list
# of string
def countString(m, n, arr, i):
     
    # Base Case if count of 0's or 1's
    # becomes negative
    if (m < 0 or n < 0):
        return -sys.maxsize - 1
 
    # If index reaches out of bound
    if (i >= len(arr)):
        return 0
 
    # Return the prestored result
    if (dp[m][n][i] != -1):
        return dp[m][n][i]
 
    # Initialize count of 0's and 1's
    # to 0 for the current state
    zero = 0
    one = 0
 
    # Calculate the number of 1's and
    # 0's in current string
    for c in arr[i]:
        if (c == '0'):
            zero += 1
        else:
            one += 1
 
    # Include the current string and
    # recur for the next iteration
    x = 1 + countString(m - zero, n - one, arr, i + 1)
 
    # Exclude the current string and
    # recur for the next iteration
    y = countString(m, n, arr, i + 1)
     
    dp[m][n][i] = max(x, y)
 
    # Update the maximum of the above
    # two states to the current dp state
    return dp[m][n][i]
 
# Driver Code
if __name__ == '__main__':
    arr = ["10", "0001", "1","111001", "0"]
 
    # N 0's and M 1's
    N = 3
    M = 5
 
    # Function call
    print(countString(M, N, arr, 0))
     
# This code is contributed by Surendra_Gangwar


C#




// C# program for the above approach
using System;
 
class GFG{
   
// 3D dp table to store the state value
static int [,,]dp = new int[100, 100, 100];
   
// Function that count the combination
// of 0's and 1's from the given list
// of String
static int countString(int m, int n,
                String []arr, int i)
{
    // Base Case if count of 0's or 1's
    // becomes negative
    if (m < 0 || n < 0) {
        return int.MinValue;
    }
   
    // If index reaches out of bound
    if (i >= arr.Length) {
        return 0;
    }
   
    // Return the prestored result
    if (dp[m, n, i] != -1) {
        return dp[m, n, i];
    }
   
    // Initialize count of 0's and 1's
    // to 0 for the current state
    int zero = 0, one = 0;
   
    // Calculate the number of 1's and
    // 0's in current String
    foreach (char c in arr[i].ToCharArray()) {
        if (c == '0') {
            zero++;
        }
        else {
            one++;
        }
    }
   
    // Include the current String and
    // recur for the next iteration
    int x = 1 + countString(m - zero,
                            n - one,
                            arr, i + 1);
   
    // Exclude the current String and
    // recur for the next iteration
    int y = countString(m, n, arr, i + 1);
   
    // Update the maximum of the above
    // two states to the current dp state
    return dp[m, n, i] = Math.Max(x, y);
}
   
// Driver Code
public static void Main(String[] args)
{
    String []arr = { "10", "0001", "1",
                           "111001", "0" };
   
    // N 0's and M 1's
    int N = 3, M = 5;
   
    // Initialize dp array to -1
    for(int i = 0; i < 100; i++){
        for(int j = 0; j < 100; j++){
            for(int l = 0; l < 100; l++)
            dp[i, j, l] = -1;
        }
    }
   
    // Function call
    Console.Write(countString(M, N, arr, 0));
}
}
 
// This code is contributed by Rajput-Ji


Javascript




<script>
 
// Javascript program for the above approach
  
// 3D dp table to store the state value
let dp = new Array();
 
// Initialize dp array to -1
for(let i = 0; i < 100; i++)
{
    dp[i] = new Array();
     for(let j = 0; j < 100; j++)
     {
          dp[i][j] = new Array();
        for(let l = 0; l < 100; l++)
        {
            dp[i][j][l] = -1;
        }
     }
  
// Function that count the combination
// of 0's and 1's from the given list
// of String
function countString(m, n, arr, i)
{
     
    // Base Case if count of 0's or 1's
    // becomes negative
    if (m < 0 || n < 0)
    {
        return Number.MIN_VALUE;
    }
  
    // If index reaches out of bound
    if (i >= arr.length)
    {
        return 0;
    }
  
    // Return the prestored result
    if (dp[m][n][i] != -1)
    {
        return dp[m][n][i];
    }
  
    // Initialize count of 0's and 1's
    // to 0 for the current state
    let zero = 0, one = 0;
  
    // Calculate the number of 1's and
    // 0's in current String
    for(let c = 0; c < arr[i].length; c++)
    {
        if (arr[i] == '0')
        {
            zero++;
        }
        else
        {
            one++;
        }
    }
  
    // Include the current String and
    // recur for the next iteration
    let x = 1 + countString(m - zero,
                            n - one,
                       arr, i + 1);
  
    // Exclude the current String and
    // recur for the next iteration
    let y = countString(m, n, arr, i + 1);
  
    // Update the maximum of the above
    // two states to the current dp state
    return dp[m][n][i] = Math.max(x, y);
}
  
// Driver Code
let arr = [ "10", "0001", "1", "111001", "0" ];
 
// N 0's and M 1's
let N = 3, M = 5;
 
// Function call
document.write(countString(M, N, arr, 0));
 
// This code is contributed by Dharanendra L V.
 
</script>


Output: 

4

 

Time Complexity: O(N*M*len), where N and M are the numbers of 1’s and 0’s respectively and len is the length of the list.
Auxiliary Space: O(N*M*len)

Efficient approach : DP tabulation (iterative)

The approach to solve this problem is same but DP tabulation(bottom-up) method is better than Dp + memorization(top-down) because memorization method needs extra stack space of recursion calls. In this approach we use 3D DP store computation of subproblems and find the final result using iteration and not with the help of recursion.

Implementation Steps:

  • Create a 3D DP table of size (N+1) * (m+1) * (n+1), where N is the number of strings in the given array, m is the maximum count of 0’s and n is the maximum count of 1’s.
  • Initialize the DP table with 0 and also set the base cases.
  • Iterate through all the states (i, j, k), where i represents the current string, j represents the count of 0’s and k represents the count of 1’s.
  • Include the current string and find the number of combinations for the next iteration by checking if the current count of 0’s and 1’s is less than or equal to the maximum counts of 0’s and 1’s respectively, and adding 1 to the value of dp[i+1][j-zero][k-one].
  • Exclude the current string and find the number of combinations for the next iteration by taking the value of dp[i+1][j][k].
  • Update the maximum of the above two states to the current DP state dp[i][j][k].
  • Return the final DP state dp[0][m][n].

Implementation :

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function that count the combination
// of 0's and 1's from the given list
// of string
int countString(int m, int n, vector<string>& arr)
{
 
    int N = arr.size();
 
    // 3D DP table to store the state value
    int dp[N + 1][m + 1][n + 1];
 
    // Initialize the DP table with 0
    memset(dp, 0, sizeof(dp));
 
    // Initialize the DP table for base case
    for (int i = 0; i <= m; i++)
        for (int j = 0; j <= n; j++)
            dp[N][i][j] = 0;
 
    // Iterate through all the states
    for (int i = N - 1; i >= 0; i--) {
        for (int j = 0; j <= m; j++) {
            for (int k = 0; k <= n; k++) {
 
                // Initialize count of 0's and 1's
                // to 0 for the current state
                int zero = 0, one = 0;
 
                // Calculate the number of 1's and 0's
                // in the current string
                for (char c : arr[i]) {
                    if (c == '0') {
                        zero++;
                    }
                    else {
                        one++;
                    }
                }
 
                // Include the current string and
                // find the number of combinations
                // for the next iteration
                int x = (j - zero < 0 || k - one < 0)
                            ? INT_MIN
                            : (1
                               + dp[i + 1][j - zero]
                                   [k - one]);
 
                // Exclude the current string and
                // find the number of combinations
                // for the next iteration
                int y = dp[i + 1][j][k];
 
                // Update the maximum of the above
                // two states to the current DP state
                dp[i][j][k] = max(x, y);
            }
        }
    }
 
    // Return the final DP state
    return dp[0][m][n];
}
// Driver Code
int main()
{
    vector<string> arr
        = { "10", "0001", "1", "111001", "0" };
 
    // N 0's and M 1's
    int N = 3, M = 5;
 
    // Function call
    cout << countString(M, N, arr);
}


Java




// Java program for the above approach
import java.util.*;
 
public class Main {
    public static int countString(int m, int n,
                                  List<String> arr)
    {
        int N = arr.size();
 
        // 3D DP table to store the state value
        int[][][] dp = new int[N + 1][m + 1][n + 1];
 
        // Initialize the DP table with 0
        for (int[][] row : dp) {
            for (int[] col : row) {
                Arrays.fill(col, 0);
            }
        }
 
        // Initialize the DP table for base case
        for (int i = 0; i <= m; i++) {
            for (int j = 0; j <= n; j++) {
                dp[N][i][j] = 0;
            }
        }
 
        // Iterate through all the states
        for (int i = N - 1; i >= 0; i--) {
            for (int j = 0; j <= m; j++) {
                for (int k = 0; k <= n; k++) {
 
                    // Initialize count of 0's and 1's
                    // to 0 for the current state
                    int zero = 0, one = 0;
 
                    // Calculate the number of 1's and 0's
                    // in the current string
                    for (char c :
                         arr.get(i).toCharArray()) {
                        if (c == '0') {
                            zero++;
                        }
                        else {
                            one++;
                        }
                    }
 
                    // Include the current string and
                    // find the number of combinations
                    // for the next iteration
                    int x = (j - zero < 0 || k - one < 0)
                                ? Integer.MIN_VALUE
                                : (1
                                   + dp[i + 1][j - zero]
                                       [k - one]);
 
                    // Exclude the current string and
                    // find the number of combinations
                    // for the next iteration
                    int y = dp[i + 1][j][k];
 
                    // Update the maximum of the above
                    // two states to the current DP state
                    dp[i][j][k] = Math.max(x, y);
                }
            }
        }
 
        // Return the final DP state
        return dp[0][m][n];
    }
 
    public static void main(String[] args)
    {
        List<String> arr = new ArrayList<>();
        arr.add("10");
        arr.add("0001");
        arr.add("1");
        arr.add("111001");
        arr.add("0");
 
        // N 0's and M 1's
        int N = 3, M = 5;
 
        // Function call
        System.out.println(countString(M, N, arr));
    }
}


Python3




# Function that count the combination
# of 0's and 1's from the given list
# of string
def countString(m, n, arr):
 
    N = len(arr)
 
    # 3D DP table to store the state value
    dp = [[[0 for _ in range(n+1)] for _ in range(m+1)] for _ in range(N+1)]
 
    # Initialize the DP table for base case
    for i in range(m+1):
        for j in range(n+1):
            dp[N][i][j] = 0
 
    # Iterate through all the states
    for i in range(N-1, -1, -1):
        for j in range(m+1):
            for k in range(n+1):
 
                # Initialize count of 0's and 1's
                # to 0 for the current state
                zero, one = 0, 0
 
                # Calculate the number of 1's and 0's
                # in the current string
                for c in arr[i]:
                    if c == '0':
                        zero += 1
                    else:
                        one += 1
 
                # Include the current string and
                # find the number of combinations
                # for the next iteration
                x = 1 + dp[i+1][j-zero][k-one] if j-zero >= 0 and k-one >= 0 else float('-inf')
 
                # Exclude the current string and
                # find the number of combinations
                # for the next iteration
                y = dp[i+1][j][k]
 
                # Update the maximum of the above
                # two states to the current DP state
                dp[i][j][k] = max(x, y)
 
    # Return the final DP state
    return dp[0][m][n]
 
# Driver Code
arr = ["10", "0001", "1", "111001", "0"]
N, M = 3, 5
print(countString(M, N, arr))


C#




using System;
using System.Collections.Generic;
 
class Program {
    static int CountStrings(int m, int n, List<string> arr) {
        int N = arr.Count;
 
        // 3D DP table to store the state value
        int[,,] dp = new int[N + 1, m + 1, n + 1];
 
        // Initialize the DP table with 0
        for (int i = 0; i <= N; i++) {
            for (int j = 0; j <= m; j++) {
                for (int k = 0; k <= n; k++) {
                    dp[i, j, k] = 0;
                }
            }
        }
 
        // Initialize the DP table for base case
        for (int i = 0; i <= m; i++) {
            for (int j = 0; j <= n; j++) {
                dp[N, i, j] = 0;
            }
        }
 
        // Iterate through all the states
        for (int i = N - 1; i >= 0; i--) {
            for (int j = 0; j <= m; j++) {
                for (int k = 0; k <= n; k++) {
 
                    // Initialize count of 0's and 1's
                    // to 0 for the current state
                    int zero = 0, one = 0;
 
                    // Calculate the number of 1's and 0's
                    // in the current string
                    foreach (char c in arr[i]) {
                        if (c == '0') {
                            zero++;
                        }
                        else {
                            one++;
                        }
                    }
 
                    // Include the current string and
                    // find the number of combinations
                    // for the next iteration
                    int x = (j - zero < 0 || k - one < 0) ? int.MinValue : (1 + dp[i + 1, j - zero, k - one]);
 
                    // Exclude the current string and
                    // find the number of combinations
                    // for the next iteration
                    int y = dp[i + 1, j, k];
 
                    // Update the maximum of the above
                    // two states to the current DP state
                    dp[i, j, k] = Math.Max(x, y);
                }
            }
        }
 
        // Return the final DP state
        return dp[0, m, n];
    }
 
    static void Main(string[] args) {
        List<string> arr = new List<string> { "10", "0001", "1", "111001", "0" };
 
        // N 0's and M 1's
        int N = 3, M = 5;
 
        // Function call
        Console.WriteLine(CountStrings(M, N, arr));
    }
}


Javascript




// Javascript program for the above approach.
 
// Function that count the combination
// of 0's and 1's from the given list
// of string
function countString(m, n, arr) {
  const N = arr.length;
 
  // 3D DP table to store the state value
  const dp = new Array(N + 1).fill(null).map(() =>
    new Array(m + 1).fill(null).map(() =>
      new Array(n + 1).fill(null)));
 
  // Initialize the DP table with 0
  for (let i = 0; i <= N; i++) {
    for (let j = 0; j <= m; j++) {
      for (let k = 0; k <= n; k++) {
        dp[i][j][k] = 0;
      }
    }
  }
 
  // Initialize the DP table for base case
  for (let i = 0; i <= m; i++) {
    for (let j = 0; j <= n; j++) {
      dp[N][i][j] = 0;
    }
  }
 
  // Iterate through all the states
  for (let i = N - 1; i >= 0; i--) {
    for (let j = 0; j <= m; j++) {
      for (let k = 0; k <= n; k++) {
        // Initialize count of 0's and 1's
        // to 0 for the current state
        let zero = 0, one = 0;
 
        // Calculate the number of 1's and 0's
        // in the current string
        for (let c of arr[i]) {
          if (c === '0') {
            zero++;
          } else {
            one++;
          }
        }
 
        // Include the current string and
        // find the number of combinations
        // for the next iteration
        let x = (j - zero < 0 || k - one < 0)
          ? Number.MIN_SAFE_INTEGER
          : (1 + dp[i + 1][j - zero][k - one]);
 
        // Exclude the current string and
        // find the number of combinations
        // for the next iteration
        let y = dp[i + 1][j][k];
 
        // Update the maximum of the above
        // two states to the current DP state
        dp[i][j][k] = Math.max(x, y);
      }
    }
  }
 
  // Return the final DP state
  return dp[0][m][n];
}
 
// Driver Code
const arr = ["10", "0001", "1", "111001", "0"];
 
// N 0's and M 1's
const N = 3, M = 5;
 
// Function call
console.log(countString(M, N, arr));
 
// The code is contributed by Arushi Goel.


Output

4

Time Complexity: O(N*M*len)
Auxiliary Space: O(N*M*len)



Last Updated : 27 Apr, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads