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

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 4
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:

Below is the implementation of the above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to implement the
// above approach
#include <bits/stdc++.h>
using namespace std;
  
// Fucntion to pre-store primes
void SieveOfEratosthenes(int MAX, vector<int>& primes)
{
    bool prime[MAX + 1];
    memset(prime, true, sizeof(prime));
  
    // Seive 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);
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to implement the 
// above approach
import java.util.HashMap;
import java.util.Vector;
  
class GFG 
{
  
    // Fucntion 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;
  
        // Seive 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
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to implement the 
# above approach 
  
from math import sqrt
  
# Fucntion to pre-store primes 
def SieveOfEratosthenes(MAX, primes) : 
  
    prime = [True]*(MAX + 1); 
  
    # Seive 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
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to implement the 
// above approach
using System;
using System.Collections.Generic; 
  
class GFG 
{
  
    // Fucntion 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;
  
        // Seive 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
chevron_right

Output:
5

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




Striver(underscore)79 at Codechef and codeforces D

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : AnkitRai01, sanjeev2552, Rajput-Ji



Article Tags :