Longest subsequence with a given OR value : Dynamic Programming Approach
Last Updated :
23 Dec, 2022
Given an array arr[], the task is to find the longest subsequence with a given OR value M. If there is no such sub-sequence then print 0.
Examples:
Input: arr[] = {3, 7, 2, 3}, M = 3
Output: 3
{3, 2, 3} is the required subsequence
3 | 2 | 3 = 3
Input: arr[] = {2, 2}, M = 3
Output: 0
Approach: A simple solution is to generate all the possible sub-sequences and then find the largest among them with the required OR value. However, for smaller values of M, a dynamic programming approach can be used.
Let’s look at the recurrence relation first.
dp[i][curr_or] = max(dp[i + 1][curr_or], dp[i + 1][curr_or | arr[i]] + 1)
Let’s understand the states of DP now. Here, dp[i][curr_or] stores the longest subsequence of the subarray arr[i…N-1] such the curr_or gives M when gets ORed with this subsequence. At each step, either choose the index i and update curr_or or reject index i and continue.
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, 0, n, m);
if (ans == -1)
cout << 0;
else
cout << ans;
return 0;
}
|
Java
class GFG
{
static int maxN = 20 ;
static int maxM = 64 ;
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 , 0 , n, m);
if (ans == - 1 )
System.out.println( 0 );
else
System.out.println(ans);
}
}
|
Python3
import numpy as np
maxN = 20
maxM = 64
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 , 0 , n, m);
if (ans = = - 1 ) :
print ( 0 );
else :
print (ans);
|
C#
using System;
class GFG
{
static int maxN = 20;
static int maxM = 64;
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, 0, 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, 0, n, m);
if (ans == -1)
document.write( 0);
else
document.write( ans);
</script>
|
Time Complexity: O(N * maxArr) where maxArr is the maximum element from the array.
Auxiliary Space: O(maxN * maxM)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...