📌  相关文章
📜  可被 3 整除的二进制字符串的非零长度子序列的数量

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

给定长度为N的二进制字符串S ,任务是找到可被3整除的非零长度子序列的数量。子序列中允许有前导零。
例子:

天真的方法:生成所有可能的子序列并检查它们是否可以被 3 整除。时间复杂度为 O((2 N ) * N)。
更好的方法:动态规划可以用来解决这个问题。让我们看看DP的状态。
DP[i][r]将存储子串S[i…N-1]的子序列的数量,这样当除以3时,它们的余数为(3 – r) % 3
现在让我们写下递推关系。

由于以下两个选择,推导了重复:

  1. 在子序列中包含当前索引i 。因此, r将更新为r = (r * 2 + s[i]) % 3
  2. 不要在子序列中包含当前索引。

下面是上述方法的实现:

C++
// C++ implementation of th approach
#include 
using namespace std;
#define N 100
 
int dp[N][3];
bool v[N][3];
 
// Function to return the number of
// sub-sequences divisible by 3
int findCnt(string& s, int i, int r)
{
    // Base-cases
    if (i == s.size()) {
        if (r == 0)
            return 1;
        else
            return 0;
    }
 
    // If the state has been solved
    // before then return its value
    if (v[i][r])
        return dp[i][r];
 
    // Marking the state as solved
    v[i][r] = 1;
 
    // Recurrence relation
    dp[i][r]
        = findCnt(s, i + 1, (r * 2 + (s[i] - '0')) % 3)
          + findCnt(s, i + 1, r);
 
    return dp[i][r];
}
 
// Driver code
int main()
{
    string s = "11";
 
    cout << (findCnt(s, 0, 0) - 1);
 
    return 0;
}


Java
// Java implementation of th approach
class GFG
{
 
    static final int N = 100;
     
    static int dp[][] = new int[N][3];
    static int v[][] = new int[N][3];
     
    // Function to return the number of
    // sub-sequences divisible by 3
    static int findCnt(String s, int i, int r)
    {
        // Base-cases
        if (i == s.length())
        {
            if (r == 0)
                return 1;
            else
                return 0;
        }
     
        // If the state has been solved
        // before then return its value
        if (v[i][r] == 1)
            return dp[i][r];
     
        // Marking the state as solved
        v[i][r] = 1;
     
        // Recurrence relation
        dp[i][r] = findCnt(s, i + 1, (r * 2 + (s.charAt(i) - '0')) % 3)
                    + findCnt(s, i + 1, r);
     
        return dp[i][r];
    }
     
    // Driver code
    public static void main (String[] args)
    {
        String s = "11";
     
        System.out.print(findCnt(s, 0, 0) - 1);
     
    }
}
 
// This code is contributed by AnkitRai01


Python3
# Python3 implementation of th approach
import numpy as np
N = 100
 
dp = np.zeros((N, 3));
v = np.zeros((N, 3));
 
# Function to return the number of
# sub-sequences divisible by 3
def findCnt(s, i, r) :
 
    # Base-cases
    if (i == len(s)) :
         
        if (r == 0) :
            return 1;
        else :
            return 0;
 
    # If the state has been solved
    # before then return its value
    if (v[i][r]) :
        return dp[i][r];
 
    # Marking the state as solved
    v[i][r] = 1;
 
    # Recurrence relation
    dp[i][r] = findCnt(s, i + 1, (r * 2 +
                      (ord(s[i]) - ord('0'))) % 3) + \
               findCnt(s, i + 1, r);
 
    return dp[i][r];
 
# Driver code
if __name__ == "__main__" :
 
    s = "11";
 
    print(findCnt(s, 0, 0) - 1);
 
# This code is contributed by AnkitRai01


C#
// C# implementation of th approach
using System;
 
class GFG
{
 
    static readonly int N = 100;
     
    static int [,]dp = new int[N, 3];
    static int [,]v = new int[N, 3];
     
    // Function to return the number of
    // sub-sequences divisible by 3
    static int findCnt(String s, int i, int r)
    {
        // Base-cases
        if (i == s.Length)
        {
            if (r == 0)
                return 1;
            else
                return 0;
        }
     
        // If the state has been solved
        // before then return its value
        if (v[i, r] == 1)
            return dp[i, r];
     
        // Marking the state as solved
        v[i, r] = 1;
     
        // Recurrence relation
        dp[i, r] = findCnt(s, i + 1, (r * 2 + (s[i] - '0')) % 3)
                    + findCnt(s, i + 1, r);
     
        return dp[i, r];
    }
     
    // Driver code
    public static void Main(String[] args)
    {
        String s = "11";
     
        Console.Write(findCnt(s, 0, 0) - 1);
     
    }
}
 
// This code is contributed by 29AjayKumar


Javascript


输出:
1

时间复杂度: O(n)

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