Dado y . La tarea es encontrar el número de strings binarias de longitud n de 2 n tal que satisfagan f(string de bits) = k.
Dónde,
f(x) = Number of times a set bit is adjacent to another set bit in a binary string x. For Example: f(011101101) = 3 f(010100000) = 0 f(111111111) = 8
Ejemplos :
Input : n = 5, k = 2 Output : 6 Explanation There are 6 ways to form bit strings of length 5 such that f(bit string s) = 2, These possible strings are:- 00111, 01110, 10111, 11011, 11100, 11101
Método 1 (Fuerza bruta): El enfoque más simple es resolver el problema recursivamente, pasando el índice actual, el valor de f (string de bits) formado hasta el índice actual y el último bit que colocamos en la string binaria formada hasta (índice actual – 1). Si alcanzamos el índice donde el índice actual = n y el valor de f (string de bits) = k , contamos de esta manera, de lo contrario no lo hacemos.
A continuación se muestra la implementación del enfoque de fuerza bruta:
C++
// C++ program to find the number of Bit Strings // of length N with K adjacent set bits #include <bits/stdc++.h> using namespace std; // Function to find the number of Bit Strings // of length N with K adjacent set bits int waysToKAdjacentSetBits(int n, int k, int currentIndex, int adjacentSetBits, int lastBit) { /* Base Case when we form bit string of length n */ if (currentIndex == n) { // if f(bit string) = k, count this way if (adjacentSetBits == k) return 1; return 0; } int noOfWays = 0; /* Check if the last bit was set, if it was set then call for next index by incrementing the adjacent bit count else just call the next index with same value of adjacent bit count and either set the bit at current index or let it remain unset */ if (lastBit == 1) { // set the bit at currentIndex noOfWays += waysToKAdjacentSetBits(n, k, currentIndex + 1, adjacentSetBits + 1, 1); // unset the bit at currentIndex noOfWays += waysToKAdjacentSetBits(n, k,currentIndex + 1, adjacentSetBits, 0); } else if (!lastBit) { noOfWays += waysToKAdjacentSetBits(n, k, currentIndex + 1, adjacentSetBits, 1); noOfWays += waysToKAdjacentSetBits(n, k, currentIndex + 1, adjacentSetBits, 0); } return noOfWays; } // Driver Code int main() { int n = 5, k = 2; /* total ways = (ways by placing 1st bit as 1 + ways by placing 1st bit as 0) */ int totalWays = waysToKAdjacentSetBits(n, k, 1, 0, 1) + waysToKAdjacentSetBits(n, k, 1, 0, 0); cout << "Number of ways = " << totalWays << "\n"; return 0; }
Java
// Java program to find the number of Bit Strings // of length N with K adjacent set bits import java.util.*; class solution { // Function to find the number of Bit Strings // of length N with K adjacent set bits static int waysToKAdjacentSetBits(int n, int k, int currentIndex, int adjacentSetBits, int lastBit) { // Base Case when we form bit string of length n if (currentIndex == n) { // if f(bit string) = k, count this way if (adjacentSetBits == k) return 1; return 0; } int noOfWays = 0; /* Check if the last bit was set, if it was set then call for next index by incrementing the adjacent bit count else just call the next index with same value of adjacent bit count and either set the bit at current index or let it remain unset */ if (lastBit == 1) { // set the bit at currentIndex noOfWays += waysToKAdjacentSetBits(n, k, currentIndex + 1, adjacentSetBits + 1, 1); // unset the bit at currentIndex noOfWays += waysToKAdjacentSetBits(n, k,currentIndex + 1, adjacentSetBits, 0); } else if (lastBit == 0) { noOfWays += waysToKAdjacentSetBits(n, k, currentIndex + 1, adjacentSetBits, 1); noOfWays += waysToKAdjacentSetBits(n, k, currentIndex + 1, adjacentSetBits, 0); } return noOfWays; } // Driver Code public static void main(String args[]) { int n = 5, k = 2; /* total ways = (ways by placing 1st bit as 1 + ways by placing 1st bit as 0) */ int totalWays = waysToKAdjacentSetBits(n, k, 1, 0, 1) + waysToKAdjacentSetBits(n, k, 1, 0, 0); System.out.println("Number of ways = "+totalWays); } } //This code is contributed by // Surendra _Gangwar
Python 3
# Python 3 program to find the number of Bit # Strings of length N with K adjacent set bits # Function to find the number of Bit Strings # of length N with K adjacent set bits def waysToKAdjacentSetBits(n, k, currentIndex, adjacentSetBits, lastBit): # Base Case when we form bit string of length n if (currentIndex == n): # if f(bit string) = k, count this way if (adjacentSetBits == k): return 1; return 0 noOfWays = 0 # Check if the last bit was set, if it was set # then call for next index by incrementing the # adjacent bit count else just call the next # index with same value of adjacent bit count # and either set the bit at current index or # let it remain unset if (lastBit == 1): # set the bit at currentIndex noOfWays += waysToKAdjacentSetBits(n, k, currentIndex + 1, adjacentSetBits + 1, 1); # unset the bit at currentIndex noOfWays += waysToKAdjacentSetBits(n, k,currentIndex + 1, adjacentSetBits, 0); elif (lastBit != 1): noOfWays += waysToKAdjacentSetBits(n, k, currentIndex + 1, adjacentSetBits, 1); noOfWays += waysToKAdjacentSetBits(n, k, currentIndex + 1, adjacentSetBits, 0); return noOfWays; # Driver Code n = 5; k = 2; # total ways = (ways by placing 1st bit as 1 + # ways by placing 1st bit as 0) totalWays = (waysToKAdjacentSetBits(n, k, 1, 0, 1) + waysToKAdjacentSetBits(n, k, 1, 0, 0)); print("Number of ways =", totalWays); # This code is contributed by Akanksha Rai
C#
// C# program to find the number of Bit Strings // of length N with K adjacent set bits using System; class GFG { // Function to find the number of Bit Strings // of length N with K adjacent set bits static int waysToKAdjacentSetBits(int n, int k, int currentIndex, int adjacentSetBits, int lastBit) { /* Base Case when we form bit string of length n */ if (currentIndex == n) { // if f(bit string) = k, count this way if (adjacentSetBits == k) return 1; return 0; } int noOfWays = 0; /* Check if the last bit was set, if it was set then call for next index by incrementing the adjacent bit count else just call the next index with same value of adjacent bit count and either set the bit at current index or let it remain unset */ if (lastBit == 1) { // set the bit at currentIndex noOfWays += waysToKAdjacentSetBits(n, k, currentIndex + 1, adjacentSetBits + 1, 1); // unset the bit at currentIndex noOfWays += waysToKAdjacentSetBits(n, k,currentIndex + 1, adjacentSetBits, 0); } else if (lastBit != 1) { noOfWays += waysToKAdjacentSetBits(n, k, currentIndex + 1, adjacentSetBits, 1); noOfWays += waysToKAdjacentSetBits(n, k, currentIndex + 1, adjacentSetBits, 0); } return noOfWays; } // Driver Code public static void Main() { int n = 5, k = 2; /* total ways = (ways by placing 1st bit as 1 + ways by placing 1st bit as 0) */ int totalWays = waysToKAdjacentSetBits(n, k, 1, 0, 1) + waysToKAdjacentSetBits(n, k, 1, 0, 0); Console.WriteLine("Number of ways = " + totalWays); } } // This code is contributed // by Akanksha Rai
PHP
<?php // PHP program to find the number of // Bit Strings of length N with K // adjacent set bits // Function to find the number of Bit Strings // of length N with K adjacent set bits function waysToKAdjacentSetBits($n, $k, $currentIndex, $adjacentSetBits, $lastBit) { /* Base Case when we form bit string of length n */ if ($currentIndex == $n) { // if f(bit string) = k, count this way if ($adjacentSetBits == $k) return 1; return 0; } $noOfWays = 0; /* Check if the last bit was set, if it was set then call for next index by incrementing the adjacent bit count else just call the next index with same value of adjacent bit count and either set the bit at current index or let it remain unset */ if ($lastBit == 1) { // set the bit at currentIndex $noOfWays += waysToKAdjacentSetBits($n, $k, $currentIndex + 1, $adjacentSetBits + 1, 1); // unset the bit at currentIndex $noOfWays += waysToKAdjacentSetBits($n, $k,$currentIndex + 1, $adjacentSetBits, 0); } else if (!$lastBit) { $noOfWays += waysToKAdjacentSetBits($n, $k, $currentIndex + 1, $adjacentSetBits, 1); $noOfWays += waysToKAdjacentSetBits($n, $k, $currentIndex + 1, $adjacentSetBits, 0); } return $noOfWays; } // Driver Code $n = 5; $k = 2; /* total ways = (ways by placing 1st bit as 1 + ways by placing 1st bit as 0) */ $totalWays = waysToKAdjacentSetBits($n, $k, 1, 0, 1) + waysToKAdjacentSetBits($n, $k, 1, 0, 0); echo "Number of ways = ", $totalWays, "\n"; // This code is contributed by ajit ?>
Javascript
<script> // Javascript program to find the number of Bit Strings // of length N with K adjacent set bits // Function to find the number of Bit Strings // of length N with K adjacent set bits function waysToKAdjacentSetBits(n, k, currentIndex, adjacentSetBits, lastBit) { /* Base Case when we form bit string of length n */ if (currentIndex == n) { // if f(bit string) = k, count this way if (adjacentSetBits == k) return 1; return 0; } let noOfWays = 0; /* Check if the last bit was set, if it was set then call for next index by incrementing the adjacent bit count else just call the next index with same value of adjacent bit count and either set the bit at current index or let it remain unset */ if (lastBit == 1) { // set the bit at currentIndex noOfWays += waysToKAdjacentSetBits(n, k, currentIndex + 1, adjacentSetBits + 1, 1); // unset the bit at currentIndex noOfWays += waysToKAdjacentSetBits(n, k,currentIndex + 1, adjacentSetBits, 0); } else if (!lastBit) { noOfWays += waysToKAdjacentSetBits(n, k, currentIndex + 1, adjacentSetBits, 1); noOfWays += waysToKAdjacentSetBits(n, k, currentIndex + 1, adjacentSetBits, 0); } return noOfWays; } // Driver Code let n = 5, k = 2; /* total ways = (ways by placing 1st bit as 1 + ways by placing 1st bit as 0) */ let totalWays = waysToKAdjacentSetBits(n, k, 1, 0, 1) + waysToKAdjacentSetBits(n, k, 1, 0, 0); document.write("Number of ways = " + totalWays); </script>
Number of ways = 6
Método 2 (eficiente): en el método 1, hay subproblemas superpuestos para eliminar para los cuales podemos aplicar Programación Dinámica (Memoización).
Para optimizar el método 1, podemos aplicar la memorización a la solución recursiva anterior de modo que,
DP[i][j][k] = Number of ways to form bit string of length i with f(bit string till i) = j where the last bit is k, which can be 0 or 1 depending on whether the last bit was set or not
A continuación se muestra la implementación del enfoque eficiente:
C++
// C++ program to find the number of Bit Strings // of length N with K adjacent set bits #include <bits/stdc++.h> using namespace std; #define MAX 1000 // Function to find the number of Bit Strings // of length N with K adjacent set bits int waysToKAdjacentSetBits(int dp[][MAX][2], int n, int k, int currentIndex, int adjacentSetBits, int lastBit) { /* Base Case when we form bit string of length n */ if (currentIndex == n) { // if f(bit string) = k, count this way if (adjacentSetBits == k) return 1; return 0; } if (dp[currentIndex][adjacentSetBits][lastBit] != -1) { return dp[currentIndex][adjacentSetBits][lastBit]; } int noOfWays = 0; /* Check if the last bit was set, if it was set then call for next index by incrementing the adjacent bit count else just call the next index with same value of adjacent bit count and either set the bit at current index or let it remain unset */ if (lastBit == 1) { // set the bit at currentIndex noOfWays += waysToKAdjacentSetBits(dp, n, k, currentIndex + 1, adjacentSetBits + 1, 1); // unset the bit at currentIndex noOfWays += waysToKAdjacentSetBits(dp, n, k, currentIndex + 1, adjacentSetBits, 0); } else if (!lastBit) { noOfWays += waysToKAdjacentSetBits(dp, n, k, currentIndex + 1, adjacentSetBits, 1); noOfWays += waysToKAdjacentSetBits(dp, n, k, currentIndex + 1, adjacentSetBits, 0); } dp[currentIndex][adjacentSetBits][lastBit] = noOfWays; return noOfWays; } // Driver Code int main() { int n = 5, k = 2; /* dp[i][j][k] represents bit strings of length i with f(bit string) = j and last bit as k */ int dp[MAX][MAX][2]; memset(dp, -1, sizeof(dp)); /* total ways = (ways by placing 1st bit as 1 + ways by placing 1st bit as 0) */ int totalWays = waysToKAdjacentSetBits(dp, n, k, 1, 0, 1) + waysToKAdjacentSetBits(dp, n, k, 1, 0, 0); cout << "Number of ways = " << totalWays << "\n"; return 0; }
Java
// Java program to find the number of Bit Strings // of length N with K adjacent set bits class solution { static final int MAX=1000; // Function to find the number of Bit Strings // of length N with K adjacent set bits static int waysToKAdjacentSetBits(int dp[][][], int n, int k, int currentIndex, int adjacentSetBits, int lastBit) { /* Base Case when we form bit string of length n */ if (currentIndex == n) { // if f(bit string) = k, count this way if (adjacentSetBits == k) return 1; return 0; } if (dp[currentIndex][adjacentSetBits][lastBit] != -1) { return dp[currentIndex][adjacentSetBits][lastBit]; } int noOfWays = 0; /* Check if the last bit was set, if it was set then call for next index by incrementing the adjacent bit count else just call the next index with same value of adjacent bit count and either set the bit at current index or let it remain unset */ if (lastBit == 1) { // set the bit at currentIndex noOfWays += waysToKAdjacentSetBits(dp, n, k, currentIndex + 1, adjacentSetBits + 1, 1); // unset the bit at currentIndex noOfWays += waysToKAdjacentSetBits(dp, n, k, currentIndex + 1, adjacentSetBits, 0); } else if (lastBit==0) { noOfWays += waysToKAdjacentSetBits(dp, n, k, currentIndex + 1, adjacentSetBits, 1); noOfWays += waysToKAdjacentSetBits(dp, n, k, currentIndex + 1, adjacentSetBits, 0); } dp[currentIndex][adjacentSetBits][lastBit] = noOfWays; return noOfWays; } // Driver Code public static void main(String args[]) { int n = 5, k = 2; /* dp[i][j][k] represents bit strings of length i with f(bit string) = j and last bit as k */ int dp[][][]= new int[MAX][MAX][2]; //initialize the dp for(int i=0;i<MAX;i++) for(int j=0;j<MAX;j++) for(int k1=0;k1<2;k1++) dp[i][j][k1]=-1; /* total ways = (ways by placing 1st bit as 1 + ways by placing 1st bit as 0) */ int totalWays = waysToKAdjacentSetBits(dp, n, k, 1, 0, 1) + waysToKAdjacentSetBits(dp, n, k, 1, 0, 0); System.out.print( "Number of ways = " + totalWays + "\n"); } }
Python3
# Python3 program to find the number of Bit Strings # of length N with K adjacent set bits MAX = 1000 # Function to find the number of Bit Strings # of length N with K adjacent set bits def waysToKAdjacentSetBits(dp, n, k, currentIndex, adjacentSetBits, lastBit): """ Base Case when we form bit string of length n """ if currentIndex == n: # if f(bit string) = k, count this way if adjacentSetBits == k: return 1 return 0 if dp[currentIndex][adjacentSetBits][lastBit] != -1: return dp[currentIndex][adjacentSetBits][lastBit] noOfWays = 0 """ Check if the last bit was set, if it was set then call for next index by incrementing the adjacent bit count else just call the next index with same value of adjacent bit count and either set the bit at current index or let it remain unset """ if lastBit == 1: # set the bit at currentIndex noOfWays += waysToKAdjacentSetBits(dp, n, k, currentIndex + 1, adjacentSetBits + 1, 1) # unset the bit at currentIndex noOfWays += waysToKAdjacentSetBits(dp, n, k, currentIndex + 1, adjacentSetBits, 0) elif not lastBit: noOfWays += waysToKAdjacentSetBits(dp, n, k, currentIndex + 1, adjacentSetBits, 1) noOfWays += waysToKAdjacentSetBits(dp, n, k, currentIndex + 1, adjacentSetBits, 0) dp[currentIndex][adjacentSetBits][lastBit] = noOfWays return noOfWays n, k = 5, 2 """ dp[i][j][k] represents bit strings of length i with f(bit string) = j and last bit as k """ dp = [[[-1 for i in range(2)] for i in range(MAX)] for j in range(MAX)] """ total ways = (ways by placing 1st bit as 1 + ways by placing 1st bit as 0) """ totalWays = waysToKAdjacentSetBits(dp, n, k, 1, 0, 1) + waysToKAdjacentSetBits(dp, n, k, 1, 0, 0) print( "Number of ways =", totalWays) # This code is contributed by decode2207.
C#
using System; // C# program to find the number // of Bit Strings of length N // with K adjacent set bits class GFG { static readonly int MAX=1000; // Function to find the number // of Bit Strings of length N // with K adjacent set bits static int waysToKAdjacentSetBits(int [,,]dp, int n, int k, int currentIndex, int adjacentSetBits, int lastBit) { /* Base Case when we form bit string of length n */ if (currentIndex == n) { // if f(bit string) = k, count this way if (adjacentSetBits == k) return 1; return 0; } if (dp[currentIndex, adjacentSetBits, lastBit] != -1) { return dp[currentIndex, adjacentSetBits, lastBit]; } int noOfWays = 0; /* Check if the last bit was set, if it was set then call for next index by incrementing the adjacent bit count else just call the next index with same value of adjacent bit count and either set the bit at current index or let it remain unset */ if (lastBit == 1) { // set the bit at currentIndex noOfWays += waysToKAdjacentSetBits(dp, n, k, currentIndex + 1, adjacentSetBits + 1, 1); // unset the bit at currentIndex noOfWays += waysToKAdjacentSetBits(dp, n, k, currentIndex + 1, adjacentSetBits, 0); } else if (lastBit==0) { noOfWays += waysToKAdjacentSetBits(dp, n, k, currentIndex + 1, adjacentSetBits, 1); noOfWays += waysToKAdjacentSetBits(dp, n, k, currentIndex + 1, adjacentSetBits, 0); } dp[currentIndex,adjacentSetBits,lastBit] = noOfWays; return noOfWays; } // Driver Code public static void Main(String []args) { int n = 5, k = 2; /* dp[i,j,k] represents bit strings of length i with f(bit string) = j and last bit as k */ int [,,]dp = new int[MAX, MAX, 2]; // initialize the dp for(int i = 0; i < MAX; i++) for(int j = 0; j < MAX; j++) for(int k1 = 0; k1 < 2; k1++) dp[i, j, k1]=-1; /* total ways = (ways by placing 1st bit as 1 + ways by placing 1st bit as 0) */ int totalWays = waysToKAdjacentSetBits(dp, n, k, 1, 0, 1) + waysToKAdjacentSetBits(dp, n, k, 1, 0, 0); Console.Write( "Number of ways = " + totalWays + "\n"); } } // This code is contributed by PrinciRaj1992
Javascript
<script> // JavaScript program to find the number of Bit Strings // of length N with K adjacent set bits var MAX = 1000; // Function to find the number of Bit Strings // of length N with K adjacent set bits function waysToKAdjacentSetBits(dp, n, k, currentIndex, adjacentSetBits, lastBit) { /* Base Case when we form bit string of length n */ if (currentIndex == n) { // if f(bit string) = k, count this way if (adjacentSetBits == k) return 1; return 0; } if (dp[currentIndex][adjacentSetBits][lastBit] != -1) { return dp[currentIndex][adjacentSetBits][lastBit]; } var noOfWays = 0; /* Check if the last bit was set, if it was set then call for next index by incrementing the adjacent bit count else just call the next index with same value of adjacent bit count and either set the bit at current index or let it remain unset */ if (lastBit == 1) { // set the bit at currentIndex noOfWays += waysToKAdjacentSetBits(dp, n, k, currentIndex + 1, adjacentSetBits + 1, 1); // unset the bit at currentIndex noOfWays += waysToKAdjacentSetBits(dp, n, k, currentIndex + 1, adjacentSetBits, 0); } else if (!lastBit) { noOfWays += waysToKAdjacentSetBits(dp, n, k, currentIndex + 1, adjacentSetBits, 1); noOfWays += waysToKAdjacentSetBits(dp, n, k, currentIndex + 1, adjacentSetBits, 0); } dp[currentIndex][adjacentSetBits][lastBit] = noOfWays; return noOfWays; } // Driver Code var n = 5, k = 2; /* dp[i][j][k] represents bit strings of length i with f(bit string) = j and last bit as k */ var dp = Array.from(Array(MAX), ()=>Array(MAX)); for(var i =0; i<MAX; i++) for(var j =0; j<MAX; j++) dp[i][j] = new Array(2).fill(-1); /* total ways = (ways by placing 1st bit as 1 + ways by placing 1st bit as 0) */ var totalWays = waysToKAdjacentSetBits(dp, n, k, 1, 0, 1) + waysToKAdjacentSetBits(dp, n, k, 1, 0, 0); document.write( "Number of ways = " + totalWays + "<br>"); </script>
Number of ways = 6