Subsecuencia más larga de una string binaria divisible por 3

Dada una string binaria S de longitud N , la tarea es encontrar la longitud de la subsecuencia más larga que sea divisible por 3 . Se permiten ceros iniciales en las subsecuencias.
Ejemplos: 
 

Entrada: S = “1001” 
Salida:
La subsecuencia más larga divisible por 3 es “1001”. 
1001 = 9 que es divisible por 3.
Entrada: S = “1011” 
Salida:
 

Enfoque ingenuo: genere todas las subsecuencias posibles y verifique si son divisibles por 3 . La complejidad de tiempo para esto será O((2 N ) * N) .
Enfoque eficiente: la programación dinámica se puede utilizar para resolver este problema. Veamos los estados de DP. 
DP[i][r] almacenará la subsecuencia más larga de la substring S[i…N-1] de modo que dé un resto de (3 – r) % 3 cuando se divida por 3
Escribamos ahora la relación de recurrencia. 
 

DP[i][r] = max(1 + DP[i + 1][(r * 2 + s[i]) % 3], DP[i + 1][r]) 
 

La recurrencia se deriva de las siguientes dos opciones: 
 

  1. Incluya el índice actual i en la subsecuencia. Por lo tanto, la r se actualizará como r = (r * 2 + s[i]) % 3 .
  2. No incluya el índice actual en la subsecuencia.

A continuación se muestra la implementación del enfoque anterior: 
 

C++

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
#define N 100
 
int dp[N][3];
bool v[N][3];
 
// Function to return the length of the
// largest sub-string divisible by 3
int findLargestString(string& s, int i, int r)
{
    // Base-case
    if (i == s.size()) {
        if (r == 0)
            return 0;
        else
            return INT_MIN;
    }
 
    // 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]
        = max(1 + findLargestString(s, i + 1,
                                    (r * 2 + (s[i] - '0')) % 3),
              findLargestString(s, i + 1, r));
    return dp[i][r];
}
 
// Driver code
int main()
{
    string s = "101";
 
    cout << findLargestString(s, 0, 0);
 
    return 0;
}

Java

// Java implementation of th approach
class GFG
{
 
    final static int N = 100 ;
    final static int INT_MIN = Integer.MIN_VALUE;
     
    static int dp[][] = new int[N][3];
    static int v[][] = new int[N][3];
     
     
    // Function to return the length of the
    // largest sub-string divisible by 3
    static int findLargestString(String s, int i, int r)
    {
        // Base-case
        if (i == s.length())
        {
            if (r == 0)
                return 0;
            else
                return INT_MIN;
        }
     
        // 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] = Math.max(1 + findLargestString(s, i + 1,
                          (r * 2 + (s.charAt(i) - '0')) % 3),
                            findLargestString(s, i + 1, r));
        return dp[i][r];
    }
     
    // Driver code
    public static void main (String[] args)
    {
        String s = "101";
     
        System.out.print(findLargestString(s, 0, 0));
    }
}
 
// This code is contributed by AnkitRai01

Python3

# Python3 implementation of the approach
import numpy as np
import sys
 
N = 100
INT_MIN = -(sys.maxsize - 1)
 
dp = np.zeros((N, 3));
v = np.zeros((N, 3));
 
# Function to return the length of the
# largest sub-string divisible by 3
def findLargestString(s, i, r) :
 
    # Base-case
    if (i == len(s)) :
        if (r == 0) :
            return 0;
        else :
            return INT_MIN;
 
    # 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] = max(1 + findLargestString(s, i + 1,
                  (r * 2 + (ord(s[i]) - ord('0'))) % 3),
                       findLargestString(s, i + 1, r));
                 
    return dp[i][r];
 
# Driver code
if __name__ == "__main__" :
 
    s = "101";
 
    print(findLargestString(s, 0, 0));
 
# This code is contributed by AnkitRai01

C#

// C# implementation of th approach
using System;
using System.Collections.Generic;
 
class GFG
{
 
    readonly static int N = 100 ;
    readonly static int INT_MIN = int.MinValue;
     
    static int [,]dp = new int[N, 3];
    static int [,]v = new int[N, 3];
     
    // Function to return the length of the
    // largest sub-string divisible by 3
    static int findLargestString(String s, int i, int r)
    {
        // Base-case
        if (i == s.Length)
        {
            if (r == 0)
                return 0;
            else
                return INT_MIN;
        }
     
        // 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] = Math.Max(1 + findLargestString(s, i + 1,
                                (r * 2 + (s[i] - '0')) % 3),
                            findLargestString(s, i + 1, r));
        return dp[i, r];
    }
     
    // Driver code
    public static void Main(String[] args)
    {
        String s = "101";
     
        Console.Write(findLargestString(s, 0, 0));
    }
}
 
// This code is contributed by 29AjayKumar

Javascript

<script>
// Javascript implementation of the approach
var N = 100
 
var dp = Array.from(Array(N), ()=>Array(3));
var v = Array.from(Array(N), ()=>Array(3));
 
// Function to return the length of the
// largest sub-string divisible by 3
function findLargestString(s, i, r)
{
    // Base-case
    if (i == s.length) {
        if (r == 0)
            return 0;
        else
            return -1000000000;
    }
 
    // 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]
        = Math.max(1 + findLargestString(s, i + 1,
                                    (r * 2 + (s[i].charCodeAt(0) - '0'.charCodeAt(0))) % 3),
              findLargestString(s, i + 1, r));
    return dp[i][r];
}
 
// Driver code
var s = "101";
document.write( findLargestString(s, 0, 0));
 
// This code is contributed by noob2000.
</script>
Producción: 

2

 

Complejidad de tiempo: O(n)
 

Publicación traducida automáticamente

Artículo escrito por DivyanshuShekhar1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *