📜  具有给定 AND 值的最长子序列

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

给定一个数组arr[]和一个整数M ,任务是找到具有给定 AND 值M的最长子序列。如果没有这样的子序列,则打印0
例子:

方法:解决这个问题的一个简单方法是生成所有可能的子序列,然后找到其中具有所需 AND 值的最大子序列。
然而,对于较小的M值,可以使用基于动态规划的方法。
我们先来看递归关系。

现在让我们了解DP的状态。这里, dp[i][curr_and]存储子数组arr[i…N-1]的最长子序列,使得curr_and & 这个子序列的 AND 等于M 。在每一步,可以选择索引i更新curr_and或者可以拒绝它。
下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
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, ((1 << 8) - 1),
                      n, m);
    if (ans == -1)
        cout << 0;
    else
        cout << ans;
 
    return 0;
}


Java
// Java implementation of the approach
import java.util.*;
 
class GFG
{
static int maxN = 300;
static int maxM = 300;
 
// 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, ((1 << 8) - 1), n, m);
    if (ans == -1)
        System.out.print( 0);
    else
        System.out.print( ans);
}
}
 
// This code is contributed by Arnab Kundu


Python3
# Python3 implementation of the approach
import numpy as np
 
maxN = 20
maxM = 256
 
# 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, ((1 << 8) - 1), 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 = 300;
static int maxM = 300;
 
// 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, ((1 << 8) - 1), n, m);
    if (ans == -1)
        Console.WriteLine(0);
    else
        Console.WriteLine(ans);
}
}
 
// This code is contributed by
// sanjeev2552


Javascript


输出:
3

时间复杂度: O(N * maxVal) 其中 maxVal 是给定数组中的最大元素。

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