Open In App

Longest sub-sequence that satisfies the given conditions

Last Updated : 08 Dec, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of N integers, the task is to find the longest sub-sequence in the given array such that for all pairs from the sub-sequence (arr[i], arr[j]) where i != j either arr[i] divides arr[j] or vice versa. If no such sub-sequence exists then print -1.
Examples: 
 

Input: arr[] = {2, 4, 6, 1, 3, 11} 
Output:
Longest valid sub-sequences are {1, 2, 6} and {1, 3, 6}.
Input: arr[] = {21, 22, 6, 4, 13, 7, 332} 
Output:
 

 

Approach: This problem is a simple variation of the longest increasing sub-sequence problem. What changes is the base condition and the trick to reduce the number of computations by sorting the given array. 
 

  • First sort the given array so that we only need to check values where arr[i] > arr[j] for i > j.
  • Then we move forward using two loops, outer loop runs from 1 to N and the inner loop runs from 0 to i.
  • Now in the inner loop we have to find the number of arr[j] where j is from 0 to i – 1 which divides the element arr[i].
  • And the recurrence relation will be dp[i] = max(dp[i], 1 + dp[j]).
  • We will update the max dp[i] value in a variable named res which will be the final answer.

Below is the implementation of the above approach:

C++

 

CPP




// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to return the length of the
// longest required sub-sequence
int find(int n, int a[])
{
    // Sort the array
    sort(a, a + n);
 
    // To store the resultant length
    int res = 1;
    int dp[n];
 
    // If array contains only one element
    // then it divides itself
    dp[0] = 1;
 
    for (int i = 1; i < n; i++) {
 
        // Every element divides itself
        dp[i] = 1;
 
        // Count for all numbers which
        // are lesser than a[i]
        for (int j = 0; j < i; j++) {
 
            if (a[i] % a[j] == 0) {
 
                // If a[i] % a[j] then update the maximum
                // subsequence length,
                // dp[i] = max(dp[i], 1 + dp[j])
                // where j is in the range [0, i-1]
                dp[i] = std::max(dp[i], 1 + dp[j]);
            }
        }
 
        res = std::max(res, dp[i]);
    }
 
    // If array contains only one element
    // then i = j which doesn't satisfy the condition
    return (res == 1) ? -1 : res;
}
 
// Driver code
int main()
{
    int a[] = { 2, 4, 6, 1, 3, 11 };
    int n = sizeof(a) / sizeof(int);
 
    cout << find(n, a);
 
    return 0;
}


Java




// Java implementation of the approach
import java.util.Arrays;
import java.io.*;
 
class GFG
{
     
// Function to return the length of the
// longest required sub-sequence
static int find(int n, int a[])
{
    // Sort the array
    Arrays.sort(a);
 
    // To store the resultant length
    int res = 1;
    int dp[] = new int[n];
 
    // If array contains only one element
    // then it divides itself
    dp[0] = 1;
 
    for (int i = 1; i < n; i++)
    {
 
        // Every element divides itself
        dp[i] = 1;
 
        // Count for all numbers which
        // are lesser than a[i]
        for (int j = 0; j < i; j++)
        {
 
            if (a[i] % a[j] == 0)
            {
 
                // If a[i] % a[j] then update the maximum
                // subsequence length,
                // dp[i] = Math.max(dp[i], 1 + dp[j])
                // where j is in the range [0, i-1]
                dp[i] = Math.max(dp[i], 1 + dp[j]);
            }
        }
 
        res = Math.max(res, dp[i]);
    }
 
    // If array contains only one element
    // then i = j which doesn't satisfy the condition
    return (res == 1) ? -1 : res;
}
 
// Driver code
public static void main (String[] args)
{
    int a[] = { 2, 4, 6, 1, 3, 11 };
    int n = a.length;
 
    System.out.println (find(n, a));
}
}
 
// This code is contributed by jit_t


Python3




# Python3 implementation of the approach
 
# Function to return the length of the
# longest required sub-sequence
def find(n, a) :
 
    # Sort the array
    a.sort();
 
    # To store the resultant length
    res = 1;
    dp = [0]*n;
 
    # If array contains only one element
    # then it divides itself
    dp[0] = 1;
 
    for i in range(1, n) :
         
        # Every element divides itself
        dp[i] = 1;
 
        # Count for all numbers which
        # are lesser than a[i]
        for j in range(i) :
 
            if (a[i] % a[j] == 0) :
 
                # If a[i] % a[j] then update the maximum
                # subsequence length,
                # dp[i] = max(dp[i], 1 + dp[j])
                # where j is in the range [0, i-1]
                dp[i] = max(dp[i], 1 + dp[j]);
     
        res = max(res, dp[i]);
 
    # If array contains only one element
    # then i = j which doesn't satisfy the condition
    if (res == 1):
        return -1
    else :
        return res;
 
 
# Driver code
if __name__ == "__main__" :
 
    a = [ 2, 4, 6, 1, 3, 11 ];
    n = len(a);
 
    print(find(n, a));
     
# This code is contributed by AnkitRai01


C#




// C# implementation of the approach
using System;
 
class GFG
{
     
// Function to return the length of the
// longest required sub-sequence
static int find(int n, int []a)
{
    // Sort the array
    Array.Sort(a);
 
    // To store the resultant length
    int res = 1;
    int []dp = new int[n];
 
    // If array contains only one element
    // then it divides itself
    dp[0] = 1;
 
    for (int i = 1; i < n; i++)
    {
 
        // Every element divides itself
        dp[i] = 1;
 
        // Count for all numbers which
        // are lesser than a[i]
        for (int j = 0; j < i; j++)
        {
 
            if (a[i] % a[j] == 0)
            {
 
                // If a[i] % a[j] then update the maximum
                // subsequence length,
                // dp[i] = Math.max(dp[i], 1 + dp[j])
                // where j is in the range [0, i-1]
                dp[i] = Math.Max(dp[i], 1 + dp[j]);
            }
        }
 
        res = Math.Max(res, dp[i]);
    }
 
    // If array contains only one element
    // then i = j which doesn't satisfy the condition
    return (res == 1) ? -1 : res;
}
 
// Driver code
public static void Main ()
{
    int []a = { 2, 4, 6, 1, 3, 11 };
    int n = a.Length;
 
    Console.WriteLine(find(n, a));
}
}
 
// This code is contributed by anuj_67..


javascript




<script>
// javascript implementation of the approach
 
// Function to return the length of the
// longest required sub-sequence
function find(n , a)
{
    // Sort the array
    a.sort();
 
    // To store the resultant length
    var res = 1;
    var dp = Array.from({length: n}, (_, i) => 0);
 
    // If array contains only one element
    // then it divides itself
    dp[0] = 1;
 
    for (var i = 1; i < n; i++)
    {
 
        // Every element divides itself
        dp[i] = 1;
 
        // Count for all numbers which
        // are lesser than a[i]
        for (var j = 0; j < i; j++)
        {
 
            if (a[i] % a[j] == 0)
            {
 
                // If a[i] % a[j] then update the maximum
                // subsequence length,
                // dp[i] = Math.max(dp[i], 1 + dp[j])
                // where j is in the range [0, i-1]
                dp[i] = Math.max(dp[i], 1 + dp[j]);
            }
        }
 
        res = Math.max(res, dp[i]);
    }
 
    // If array contains only one element
    // then i = j which doesn't satisfy the condition
    return (res == 1) ? -1 : res;
}
 
// Driver code
    var a = [ 2, 4, 6, 1, 3, 11 ];
    var n = a.length;
 
    document.write(find(n, a));
 
// This code is contributed by jit_t
 
// This code is contributed by 29AjayKumar
</script>


Output: 

3

 



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads