📌  相关文章
📜  具有 K 个相邻设置位的长度为 N 的二进制串的数量

📅  最后修改于: 2021-09-17 07:29:52             🧑  作者: Mango

给定的n      k      .任务是从 2 n 中找出长度为n的二进制字符串的数量,使它们满足 f(bit 字符串) = k。
在哪里,

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

例子

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

方法1(蛮力):最简单的方法是递归解决问题,通过传递当前索引,形成直到当前索引的f(位字符串)的值以及我们放置在形成的二进制字符串的最后一位(当前索引) – 1)。如果我们到达当前索引 = nf(bit 字符串) = k的值的索引,那么我们以这种方式计算,否则我们不计算。
下面是蛮力方法的实现:

C++
// C++ program to find the number of Bit Strings
// of length N with K adjacent set bits
 
#include 
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


Javascript


C++
// C++ program to find the number of Bit Strings
// of length N with K adjacent set bits
 
#include 
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


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


输出:

Number of ways = 6

方法 2(高效):在方法 1 中,我们可以应用动态规划(Memoization)来去除重叠的子问题。
为了优化方法 1,我们可以将记忆化应用于上述递归解决方案,使得,

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

下面是高效方法的实现:

C++

// C++ program to find the number of Bit Strings
// of length N with K adjacent set bits
 
#include 
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

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


输出:
Number of ways = 6

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程