Longest subsequence with a given AND value
Last Updated :
08 Mar, 2022
Given an array arr[] and an integer M, the task is to find the longest subsequence with a given AND value M. If there is no such sub-sequence then print 0.
Examples:
Input: arr[] = {3, 7, 2, 3}, M = 3
Output: 3
Longest sub-sequence with AND value 3 is {3, 7, 3}.
Input: arr[] = {2, 2}, M = 3
Output: 0
Approach: A simple way to solve this will be to generate all the possible sub-sequences and then find the largest among them with required AND value.
However, for smaller values of M, an approach based on dynamic programming can be used.
Let’s look at the recurrence relation first.
dp[i][curr_and] = max(dp[i + 1][curr_and], dp[i + 1][curr_and & arr[i]] + 1)
Let’s understand the states of DP now. Here, dp[i][curr_and] stores the longest subsequence of subarray arr[i…N-1] such that curr_and & the AND of this subsequence is equal to M. At each step, either the index i can be chosen updating curr_and or it can be rejected.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
#define maxN 20
#define maxM 64
int dp[maxN][maxM];
bool v[maxN][maxM];
int findLen( int * arr, int i, int curr,
int n, int m)
{
if (i == n) {
if (curr == m)
return 0;
else
return -1;
}
if (v[i][curr])
return dp[i][curr];
v[i][curr] = 1;
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];
}
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
import java.util.*;
class GFG
{
static int maxN = 300 ;
static int maxM = 300 ;
static int dp[][] = new int [maxN][maxM];
static boolean v[][] = new boolean [maxN][maxM];
static int findLen( int [] arr, int i,
int curr, int n, int m)
{
if (i == n)
{
if (curr == m)
return 0 ;
else
return - 1 ;
}
if (v[i][curr])
return dp[i][curr];
v[i][curr] = true ;
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];
}
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);
}
}
|
Python3
import numpy as np
maxN = 20
maxM = 256
dp = np.zeros((maxN, maxM));
v = np.zeros((maxN, maxM));
def findLen(arr, i, curr, n, m) :
if (i = = n) :
if (curr = = m) :
return 0 ;
else :
return - 1 ;
if (v[i][curr]) :
return dp[i][curr];
v[i][curr] = 1 ;
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];
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);
|
C#
using System;
class GFG
{
static int maxN = 300;
static int maxM = 300;
static int [,] dp = new int [maxN, maxM];
static bool [,] v = new bool [maxN, maxM];
static int findLen( int [] arr, int i,
int curr, int n, int m)
{
if (i == n)
{
if (curr == m)
return 0;
else
return -1;
}
if (v[i, curr])
return dp[i, curr];
v[i, curr] = true ;
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];
}
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);
}
}
|
Javascript
<script>
var maxN = 20
var maxM = 64
var dp = Array.from(Array(maxN), ()=> Array(maxM));
var v = Array.from(Array(maxN), ()=> Array(maxM));
function findLen(arr, i, curr, n, m)
{
if (i == n) {
if (curr == m)
return 0;
else
return -1;
}
if (v[i][curr])
return dp[i][curr];
v[i][curr] = 1;
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];
}
var arr = [3, 7, 2, 3];
var n = arr.length;
var m = 3;
var ans = findLen(arr, 0, ((1 << 8) - 1),
n, m);
if (ans == -1)
document.write( 0);
else
document.write( ans);
</script>
|
Time Complexity: O(N * maxVal) where maxVal is the maximum element from the given array.
Auxiliary Space: O(maxN * maxM)
Share your thoughts in the comments
Please Login to comment...