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:

  • Initially store all the primes in any of the Data-structure.
  • 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 the n-2, and for every number multiply it with all the primes till it exceeds a[n-1] and perform the below operations.
  • 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]]).
  • At 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++

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


Python3

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


Output:

5

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



My Personal Notes arrow_drop_up

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