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++ 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 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 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# 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)