Subsecuencia más larga con un valor OR dado: enfoque de programación dinámica

Dada una array arr[] , la tarea es encontrar la subsecuencia más larga con un valor OR dado M . Si no existe tal subsecuencia, imprima 0 .

Ejemplos: 

Entrada: arr[] = {3, 7, 2, 3}, M = 3 
Salida:
{3, 2, 3} es la subsecuencia requerida 
3 | 2 | 3 = 3
Entrada: arr[] = {2, 2}, M = 3 
Salida: 0  

Enfoque: una solución simple es generar todas las subsecuencias posibles y luego encontrar la más grande entre ellas con el valor OR requerido. Sin embargo, para valores más pequeños de M , se puede utilizar un enfoque de programación dinámica .
Veamos primero la relación de recurrencia.  

dp[i][curr_or] = max(dp[i + 1][curr_or], dp[i + 1][curr_or | arr[i]] + 1) 
 

Comprendamos los estados de DP ahora. Aquí, dp[i][curr_or] almacena la subsecuencia más larga del subarreglo arr[i…N-1] tal que curr_or da M cuando obtiene OR con esta subsecuencia. En cada paso, elija el índice i y actualice curr_or o rechace el índice i y continúe.

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 maxN 20
#define maxM 64
 
// To store the states of DP
int dp[maxN][maxM];
bool v[maxN][maxM];
 
// Function to return the required length
int findLen(int* arr, int i, int curr,
            int n, int m)
{
    // Base case
    if (i == n) {
        if (curr == m)
            return 0;
        else
            return -1;
    }
 
    // If the state has been solved before
    // return the value of the state
    if (v[i][curr])
        return dp[i][curr];
 
    // Setting the state as solved
    v[i][curr] = 1;
 
    // Recurrence relation
    int l = findLen(arr, i + 1, curr, n, m);
    int r = findLen(arr, i + 1, curr | arr[i], n, m);
    dp[i][curr] = l;
    if (r != -1)
        dp[i][curr] = max(dp[i][curr], r + 1);
    return dp[i][curr];
}
 
// Driver code
int main()
{
    int arr[] = { 3, 7, 2, 3 };
    int n = sizeof(arr) / sizeof(int);
    int m = 3;
 
    int ans = findLen(arr, 0, 0, n, m);
    if (ans == -1)
        cout << 0;
    else
        cout << ans;
 
    return 0;
}

Java

// Java implementation of the approach
class GFG
{
 
static int maxN = 20;
static int maxM = 64;
 
// To store the states of DP
static int [][]dp = new int[maxN][maxM];
static boolean [][]v = new boolean[maxN][maxM];
 
// Function to return the required length
static int findLen(int[] arr, int i,
                   int curr, int n, int m)
{
    // Base case
    if (i == n)
    {
        if (curr == m)
            return 0;
        else
            return -1;
    }
 
    // If the state has been solved before
    // return the value of the state
    if (v[i][curr])
        return dp[i][curr];
 
    // Setting the state as solved
    v[i][curr] = true;
 
    // Recurrence relation
    int l = findLen(arr, i + 1, curr, n, m);
    int r = findLen(arr, i + 1, curr | arr[i], n, m);
    dp[i][curr] = l;
    if (r != -1)
        dp[i][curr] = Math.max(dp[i][curr], r + 1);
    return dp[i][curr];
}
 
// Driver code
public static void main(String []args)
{
    int arr[] = { 3, 7, 2, 3 };
    int n = arr.length;
    int m = 3;
 
    int ans = findLen(arr, 0, 0, n, m);
    if (ans == -1)
        System.out.println(0);
    else
        System.out.println(ans);
}
}
 
// This code is contributed by 29AjayKumar

Python3

# Python3 implementation of the approach
import numpy as np
 
maxN = 20
maxM = 64
 
# To store the states of DP
dp = np.zeros((maxN, maxM));
v = np.zeros((maxN, maxM));
 
# Function to return the required length
def findLen(arr, i, curr, n, m) :
 
    # Base case
    if (i == n) :
        if (curr == m) :
            return 0;
        else :
            return -1;
 
    # If the state has been solved before
    # return the value of the state
    if (v[i][curr]) :
        return dp[i][curr];
 
    # Setting the state as solved
    v[i][curr] = 1;
 
    # Recurrence relation
    l = findLen(arr, i + 1, curr, n, m);
    r = findLen(arr, i + 1, curr | arr[i], n, m);
    dp[i][curr] = l;
    if (r != -1) :
        dp[i][curr] = max(dp[i][curr], r + 1);
    return dp[i][curr];
 
# Driver code
if __name__ == "__main__" :
 
    arr = [ 3, 7, 2, 3 ];
    n = len(arr);
    m = 3;
 
    ans = findLen(arr, 0, 0, n, m);
    if (ans == -1) :
        print(0);
    else :
        print(ans);
 
# This code is contributed by AnkitRai01

C#

// C# implementation of the approach
using System;
 
class GFG
{
 
static int maxN = 20;
static int maxM = 64;
 
// To store the states of DP
static int [,]dp = new int[maxN,maxM];
static bool [,]v = new bool[maxN,maxM];
 
// Function to return the required length
static int findLen(int[] arr, int i,
                int curr, int n, int m)
{
    // Base case
    if (i == n)
    {
        if (curr == m)
            return 0;
        else
            return -1;
    }
 
    // If the state has been solved before
    // return the value of the state
    if (v[i,curr])
        return dp[i,curr];
 
    // Setting the state as solved
    v[i,curr] = true;
 
    // Recurrence relation
    int l = findLen(arr, i + 1, curr, n, m);
    int r = findLen(arr, i + 1, curr | arr[i], n, m);
    dp[i,curr] = l;
    if (r != -1)
        dp[i,curr] = Math.Max(dp[i,curr], r + 1);
    return dp[i,curr];
}
 
// Driver code
public static void Main(String []args)
{
    int []arr = { 3, 7, 2, 3 };
    int n = arr.Length;
    int m = 3;
 
    int ans = findLen(arr, 0, 0, n, m);
    if (ans == -1)
        Console.WriteLine(0);
    else
        Console.WriteLine(ans);
}
}
 
// This code is contributed by PrinciRaj1992

Javascript

<script>
 
// Javascript implementation of the approach
 
var maxN = 20
var maxM = 64
 
// To store the states of DP
var dp = Array.from(Array(maxN), ()=> Array(maxM));
var v = Array.from(Array(maxN), ()=> Array(maxM));
 
// Function to return the required length
function findLen(arr, i, curr, n, m)
{
    // Base case
    if (i == n) {
        if (curr == m)
            return 0;
        else
            return -1;
    }
 
    // If the state has been solved before
    // return the value of the state
    if (v[i][curr])
        return dp[i][curr];
 
    // Setting the state as solved
    v[i][curr] = 1;
 
    // Recurrence relation
    var l = findLen(arr, i + 1, curr, n, m);
    var r = findLen(arr, i + 1, curr | arr[i], n, m);
    dp[i][curr] = l;
    if (r != -1)
        dp[i][curr] = Math.max(dp[i][curr], r + 1);
    return dp[i][curr];
}
 
// Driver code
var arr = [3, 7, 2, 3];
var n = arr.length;
var m = 3;
var ans = findLen(arr, 0, 0, n, m);
if (ans == -1)
    document.write( 0);
else
    document.write( ans);
 
</script>
Producción: 

3

 

Complejidad de tiempo: O(N * maxArr) donde maxArr es el elemento máximo de la array.
 

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 *