Skip to content
Related Articles

Related Articles

Longest subsequence such that every element in the subsequence is formed by multiplying previous element with a prime

Improve Article
Save Article
  • Difficulty Level : Medium
  • Last Updated : 21 May, 2021
Improve Article
Save Article

Given a sorted array of N integers. The task is to find the longest subsequence such that every element in the subsequence is reachable by multiplying any prime number to the previous element in the subsequence.
Note: A[i] <= 105 

Examples: 

Input: a[] = {3, 5, 6, 12, 15, 36} 
Output
The longest subsequence is {3, 6, 12, 36} 
6 = 3*2 
12 = 6*2 
36 = 12*3 
2 and 3 are primes 

Input: a[] = {1, 2, 5, 6, 12, 35, 60, 385} 
Output: 5  

Approach: The problem can be solved using pre-storing primes till the largest number in the array and using basic Dynamic Programming. The following steps can be followed to solve the above problem:  

  • Initially, they store all the primes in any of the data structures.
  • Hash the index of the numbers in a hash-map.
  • Create a dp[] of size N, and initialize it with 1 at every place, as the longest subsequence possible is 1 only. dp[i] represents the length of the longest subsequence that can be formed with a[i] as the starting element.
  • Iterate from n-2, and for every number multiply it with all the primes till it exceeds a[n-1] and performs the operations below.
  • Multiply the number a[i] with prime to get x. If x exists in the hash-map then the recurrence will be dp[i] = max(dp[i], 1 + dp[hash[x]]).
  • In the end, iterate in dp[] array and find the maximum value which will be our answer.

Below is the implementation of the above approach: 

C++




// C++ program to implement the
// above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to pre-store primes
void SieveOfEratosthenes(int MAX, vector<int>& primes)
{
    bool prime[MAX + 1];
    memset(prime, true, sizeof(prime));
 
    // Sieve method to check if prime or not
    for (long long p = 2; p * p <= MAX; p++) {
        if (prime[p] == true) {
            // Multiples
            for (long long i = p * p; i <= MAX; i += p)
                prime[i] = false;
        }
    }
 
    // Pre-store all the primes
    for (long long i = 2; i <= MAX; i++) {
        if (prime[i])
            primes.push_back(i);
    }
}
 
// Function to find the longest subsequence
int findLongest(int A[], int n)
{
    // Hash map
    unordered_map<int, int> mpp;
    vector<int> primes;
 
    // Call the function to pre-store the primes
    SieveOfEratosthenes(A[n - 1], primes);
 
    int dp[n];
    memset(dp, 0, sizeof dp);
 
    // Initialize last element with 1
    // as that is the longest possible
    dp[n - 1] = 1;
    mpp[A[n - 1]] = n - 1;
 
    // Iterate from the back and find the longest
    for (int i = n - 2; i >= 0; i--) {
 
        // Get the number
        int num = A[i];
 
        // Initialize dp[i] as 1
        // as the element will only me in
        // the subsequence .
        dp[i] = 1;
        int maxi = 0;
 
        // Iterate in all the primes and
        // multiply to get the next element
        for (auto it : primes) {
 
            // Next element if multiplied with it
            int xx = num * it;
 
            // If exceeds the last element
            // then break
            if (xx > A[n - 1])
                break;
 
            // If the number is there in the array
            else if (mpp[xx] != 0) {
                // Get the maximum most element
                dp[i] = max(dp[i], 1 + dp[mpp[xx]]);
            }
        }
        // Hash the element
        mpp[A[i]] = i;
    }
    int ans = 1;
 
    // Find the longest
    for (int i = 0; i < n; i++) {
        ans = max(ans, dp[i]);
    }
 
    return ans;
}
// Driver Code
int main()
{
    int a[] = { 1, 2, 5, 6, 12, 35, 60, 385 };
    int n = sizeof(a) / sizeof(a[0]);
    cout << findLongest(a, n);
}

Java




// Java program to implement the
// above approach
import java.util.HashMap;
import java.util.Vector;
 
class GFG
{
 
    // Function to pre-store primes
    public static void SieveOfEratosthenes(int MAX,
                            Vector<Integer> primes)
    {
        boolean[] prime = new boolean[MAX + 1];
        for (int i = 0; i < MAX + 1; i++)
            prime[i] = true;
 
        // Sieve method to check if prime or not
        for (int p = 2; p * p <= MAX; p++)
        {
            if (prime[p] == true)
            {
                // Multiples
                for (int i = p * p; i <= MAX; i += p)
                    prime[i] = false;
            }
        }
 
        // Pre-store all the primes
        for (int i = 2; i <= MAX; i++)
        {
            if (prime[i])
                primes.add(i);
        }
    }
 
    // Function to find the intest subsequence
    public static int findLongest(int[] A, int n)
    {
 
        // Hash map
        HashMap<Integer, Integer> mpp = new HashMap<>();
        Vector<Integer> primes = new Vector<>();
 
        // Call the function to pre-store the primes
        SieveOfEratosthenes(A[n - 1], primes);
 
        int[] dp = new int[n];
 
        // Initialize last element with 1
        // as that is the intest possible
        dp[n - 1] = 1;
        mpp.put(A[n - 1], n - 1);
 
        // Iterate from the back and find the intest
        for (int i = n - 2; i >= 0; i--)
        {
 
            // Get the number
            int num = A[i];
 
            // Initialize dp[i] as 1
            // as the element will only me in
            // the subsequence .
            dp[i] = 1;
            int maxi = 0;
 
            // Iterate in all the primes and
            // multiply to get the next element
            for (int it : primes)
            {
 
                // Next element if multiplied with it
                int xx = num * it;
 
                // If exceeds the last element
                // then break
                if (xx > A[n - 1])
                    break;
 
                // If the number is there in the array
                else if (mpp.get(xx) != null && mpp.get(xx) != 0)
                {
 
                        // Get the maximum most element
                        dp[i] = Math.max(dp[i], 1 + dp[mpp.get(xx)]);
                }
            }
 
            // Hash the element
            mpp.put(A[i], i);
        }
        int ans = 1;
 
        // Find the intest
        for (int i = 0; i < n; i++)
            ans = Math.max(ans, dp[i]);
 
        return ans;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int[] a = { 1, 2, 5, 6, 12, 35, 60, 385 };
        int n = a.length;
        System.out.println(findLongest(a, n));
 
    }
}
 
// This code is contributed by
// sanjeev2552

Python3




# Python3 program to implement the
# above approach
 
from math import sqrt
 
# Function to pre-store primes
def SieveOfEratosthenes(MAX, primes) :
 
    prime = [True]*(MAX + 1);
 
    # Sieve method to check if prime or not
    for p in range(2,int(sqrt(MAX)) + 1) :
        if (prime[p] == True) :
            # Multiples
            for i in range(p**2, MAX + 1, p) :
                prime[i] = False;
 
    # Pre-store all the primes
    for i in range(2, MAX + 1) :
        if (prime[i]) :
            primes.append(i);
 
# Function to find the longest subsequence
def findLongest(A, n) :
 
    # Hash map
    mpp = {};
    primes = [];
     
    # Call the function to pre-store the primes
    SieveOfEratosthenes(A[n - 1], primes);
     
    dp = [0] * n ;
     
    # Initialize last element with 1
    # as that is the longest possible
    dp[n - 1] = 1;
    mpp[A[n - 1]] = n - 1;
     
    # Iterate from the back and find the longest
    for i in range(n-2,-1,-1) :
         
        # Get the number
        num = A[i];
         
        # Initialize dp[i] as 1
        # as the element will only me in
        # the subsequence
        dp[i] = 1;
        maxi = 0;
         
        # Iterate in all the primes and
        # multiply to get the next element
        for it in primes :
             
            # Next element if multiplied with it
            xx = num * it;
             
            # If exceeds the last element
            # then break
            if (xx > A[n - 1]) :
                break;
                 
            # If the number is there in the array
            elif xx in mpp :
                # Get the maximum most element
                dp[i] = max(dp[i], 1 + dp[mpp[xx]]);
                 
        # Hash the element
        mpp[A[i]] = i;
         
    ans = 1;
         
    # Find the longest
    for i in range(n) :
        ans = max(ans, dp[i]);
         
    return ans;
 
# Driver Code
if __name__ == "__main__" :
 
    a = [ 1, 2, 5, 6, 12, 35, 60, 385 ];
    n = len(a);
     
    print(findLongest(a, n));
 
# This code is contributed by AnkitRai01

C#




// C# program to implement the
// above approach
using System;
using System.Collections.Generic;
 
class GFG
{
 
    // Function to pre-store primes
    public static void SieveOfEratosthenes(int MAX,
                                      List<int> primes)
    {
        Boolean[] prime = new Boolean[MAX + 1];
        for (int i = 0; i < MAX + 1; i++)
            prime[i] = true;
 
        // Sieve method to check if prime or not
        for (int p = 2; p * p <= MAX; p++)
        {
            if (prime[p] == true)
            {
                // Multiples
                for (int i = p * p; i <= MAX; i += p)
                    prime[i] = false;
            }
        }
 
        // Pre-store all the primes
        for (int i = 2; i <= MAX; i++)
        {
            if (prime[i])
                primes.Add(i);
        }
    }
 
    // Function to find the intest subsequence
    public static int findLongest(int[] A, int n)
    {
 
        // Hash map
        Dictionary<int, int> mpp = new Dictionary<int, int>();
        List<int> primes = new List<int>();
 
        // Call the function to pre-store the primes
        SieveOfEratosthenes(A[n - 1], primes);
 
        int[] dp = new int[n];
 
        // Initialize last element with 1
        // as that is the intest possible
        dp[n - 1] = 1;
        mpp.Add(A[n - 1], n - 1);
 
        // Iterate from the back and find the intest
        for (int i = n - 2; i >= 0; i--)
        {
 
            // Get the number
            int num = A[i];
 
            // Initialize dp[i] as 1
            // as the element will only me in
            // the subsequence .
            dp[i] = 1;
 
            // Iterate in all the primes and
            // multiply to get the next element
            foreach (int it in primes)
            {
 
                // Next element if multiplied with it
                int xx = num * it;
 
                // If exceeds the last element
                // then break
                if (xx > A[n - 1])
                    break;
 
                // If the number is there in the array
                else if (mpp.ContainsKey(xx) && mpp[xx] != 0)
                {
 
                    // Get the maximum most element
                    dp[i] = Math.Max(dp[i], 1 + dp[mpp[xx]]);
                }
            }
 
            // Hash the element
            if(mpp.ContainsKey(A[i]))
                mpp[A[i]] = i;
            else
                mpp.Add(A[i], i);
        }
        int ans = 1;
 
        // Find the intest
        for (int i = 0; i < n; i++)
            ans = Math.Max(ans, dp[i]);
 
        return ans;
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        int[] a = { 1, 2, 5, 6, 12, 35, 60, 385 };
        int n = a.Length;
        Console.WriteLine(findLongest(a, n));
    }
}
 
// This code is contributed by Rajput-Ji

Javascript




<script>
    // Javascript program to implement the
    // above approach
 
 
    // Function to pre-store primes
    function SieveOfEratosthenes(MAX, primes) {
        let prime = new Array(MAX + 1).fill(true);
 
 
        // Sieve method to check if prime or not
        for (let p = 2; p * p <= MAX; p++) {
            if (prime[p] == true) {
            // Multiples
                for (let i = p * p; i <= MAX; i += p)
                    prime[i] = false;
            }
        }
 
        // Pre-store all the primes
        for (let i = 2; i <= MAX; i++) {
            if (prime[i])
                primes.push(i);
        }
    }   
 
    // Function to find the longest subsequence
    function findLongest(A, n) {
        // Hash map
        let mpp = new Map();
        let primes = new Array();
 
        // Call the function to pre-store the primes
        SieveOfEratosthenes(A[n - 1], primes);
 
        let dp = new Array(n);
        dp.fill(0)
 
        // Initialize last element with 1
        // as that is the longest possible
        dp[n - 1] = 1;
        mpp.set(A[n - 1], n - 1);
 
        // Iterate from the back and find the longest
        for (let i = n - 2; i >= 0; i--) {
 
            // Get the number
            let num = A[i];
 
            // Initialize dp[i] as 1
            // as the element will only me in
            // the subsequence .
            dp[i] = 1;
            let maxi = 0;
 
            // Iterate in all the primes and
            // multiply to get the next element
            for (let it of primes) {
 
                // Next element if multiplied with it
                let xx = num * it;
 
                // If exceeds the last element
                // then break
                if (xx > A[n - 1])
                    break;
 
                // If the number is there in the array
                else if (mpp.get(xx)) {
                    // Get the maximum most element
                    dp[i] = Math.max(dp[i], 1 + dp[mpp.get(xx)]);
                }
            }
            // Hash the element
            mpp.set(A[i], i);
        }
        let ans = 1;
 
        // Find the longest
        for (let i = 0; i < n; i++) {
            ans = Math.max(ans, dp[i]);
        }
 
        return ans;
    }
    // Driver Code
 
    let a = [1, 2, 5, 6, 12, 35, 60, 385];
    let n = a.length;
    document.write(findLongest(a, n));
 
 
// This code is contributed by _saurabh_jaiswal
</script>

Output: 

5

 

Time Complexity: O(N log N) 
Auxiliary Space: O(N)
 


My Personal Notes arrow_drop_up
Related Articles

Start Your Coding Journey Now!