Given two integers N and K, the task is to find the number of binary strings of length N having an even number of 1’s out of which less than K are consecutive.
Examples:
Input: N = 4, K = 2
Output: 4
Explanation:
The possible binary strings are 0000, 0101, 1001, 1010. They all have even number of 1’s with less than 2 of them occuring consecutively.Input: N = 3, K = 2
Output: 2
Explanation:
The possible binary strings are 000, 101. All other strings that is 001, 010, 011, 100, 110, 111 does not meet the criteria.
Approach:
This problem can be solved by Dynamic Programming.
Let us consider a 3D table dp[][][] to store the solution of each subproblem, such that, dp[n][i][s] denotes the number of binary strings of length n having i consecutive 1’s and sum of 1’s = s. As it is only required to check whether the total number of 1’s is even or not we store s % 2. So, dp[n][i][s] can be calculated as follows:
- If we place 0 at the nth position, the number of 1’s remain unchanged. Hence, dp[n][i][s] = dp[n – 1][0][s].
- If we place 1 at the nth position, dp[n][i][s] = dp[n – 1][i + 1][(s + 1) % 2] .
- From the above two points the recurrence relation formed is given by:
Below is the implementation of the above approach:
C++
// C++ program for the above approach #include <bits/stdc++.h> using namespace std; // Table to store solution // of each subproblem int dp[100001][20][2]; // Function to calculate // the possible binary // strings int possibleBinaries( int pos, int ones, int sum, int k) { // If number of ones // is equal to K if (ones == k) return 0; // pos: current position // Base Case: When n // length is traversed if (pos == 0) // sum: count of 1's // Return the count // of 1's obtained return (sum == 0) ? 1 : 0; // If the subproblem has already // been solved if (dp[pos][ones][sum] != -1) // Return the answer return dp[pos][ones][sum]; // Recursive call when current // position is filled with 1 int ret = possibleBinaries(pos - 1, ones + 1, (sum + 1) % 2, k) // Recursive call when current // position is filled with 0 + possibleBinaries(pos - 1, 0, sum, k); // Store the solution // to this subproblem dp[pos][ones][sum] = ret; return dp[pos][ones][sum]; } // Driver Code int main() { int N = 3; int K = 2; // Initialising the // table with -1 memset (dp, -1, sizeof dp); cout << possibleBinaries(N, 0, 0, K); } |
Java
// Java program for the above approach class GFG{ // Table to store solution // of each subproblem static int [][][]dp = new int [ 100001 ][ 20 ][ 2 ]; // Function to calculate // the possible binary // Strings static int possibleBinaries( int pos, int ones, int sum, int k) { // If number of ones // is equal to K if (ones == k) return 0 ; // pos: current position // Base Case: When n // length is traversed if (pos == 0 ) // sum: count of 1's // Return the count // of 1's obtained return (sum == 0 ) ? 1 : 0 ; // If the subproblem has already // been solved if (dp[pos][ones][sum] != - 1 ) // Return the answer return dp[pos][ones][sum]; // Recursive call when current // position is filled with 1 int ret = possibleBinaries(pos - 1 , ones + 1 , (sum + 1 ) % 2 , k) + // Recursive call when current // position is filled with 0 possibleBinaries(pos - 1 , 0 , sum, k); // Store the solution // to this subproblem dp[pos][ones][sum] = ret; return dp[pos][ones][sum]; } // Driver Code public static void main(String[] args) { int N = 3 ; int K = 2 ; // Initialising the // table with -1 for ( int i = 0 ; i < 100001 ; i++) { for ( int j = 0 ; j < 20 ; j++) { for ( int l = 0 ; l < 2 ; l++) dp[i][j][l] = - 1 ; } } System.out.print(possibleBinaries(N, 0 , 0 , K)); } } // This code is contributed by Rohit_ranjan |
Python3
# Python3 program for the above approach import numpy as np # Table to store solution # of each subproblem dp = np.ones((( 100002 , 21 , 3 ))) dp = - 1 * dp # Function to calculate # the possible binary # strings def possibleBinaries(pos, ones, sum , k): # If number of ones # is equal to K if (ones = = k): return 0 # pos: current position # Base Case: When n # length is traversed if (pos = = 0 ): # sum: count of 1's # Return the count # of 1's obtained return 1 if ( sum = = 0 ) else 0 # If the subproblem has already # been solved if (dp[pos][ones][ sum ] ! = - 1 ): # Return the answer return dp[pos][ones][ sum ] # Recursive call when current # position is filled with 1 ret = (possibleBinaries(pos - 1 , ones + 1 , ( sum + 1 ) % 2 , k) + # Recursive call when current # position is filled with 0 possibleBinaries(pos - 1 , 0 , sum , k)) # Store the solution # to this subproblem dp[pos][ones][ sum ] = ret return dp[pos][ones][ sum ] # Driver Code N = 3 K = 2 print ( int (possibleBinaries(N, 0 , 0 , K))) # This code is contributed by sanjoy_62 |
C#
// C# program for the above approach using System; class GFG{ // Table to store solution // of each subproblem static int [,,]dp = new int [100001, 20, 2]; // Function to calculate the // possible binary Strings static int possibleBinaries( int pos, int ones, int sum, int k) { // If number of ones // is equal to K if (ones == k) return 0; // pos: current position // Base Case: When n // length is traversed if (pos == 0) // sum: count of 1's // Return the count // of 1's obtained return (sum == 0) ? 1 : 0; // If the subproblem has already // been solved if (dp[pos, ones, sum] != -1) // Return the answer return dp[pos, ones, sum]; // Recursive call when current // position is filled with 1 int ret = possibleBinaries(pos - 1, ones + 1, (sum + 1) % 2, k) + // Recursive call when current // position is filled with 0 possibleBinaries(pos - 1, 0, sum, k); // Store the solution // to this subproblem dp[pos, ones, sum] = ret; return dp[pos, ones, sum]; } // Driver Code public static void Main(String[] args) { int N = 3; int K = 2; // Initialising the // table with -1 for ( int i = 0; i < 100001; i++) { for ( int j = 0; j < 20; j++) { for ( int l = 0; l < 2; l++) dp[i, j, l] = -1; } } Console.Write(possibleBinaries(N, 0, 0, K)); } } // This code is contributed by Amit Katiyar |
2
Time Complexity: O(2*N*K)