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

• Difficulty Level : Medium
• Last Updated : 21 May, 2021

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:

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

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 ``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);``    ``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 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 mpp = ``new` `HashMap<>();``        ``Vector 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

 ``
Output:
`5`

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

My Personal Notes arrow_drop_up