Longest subsequence such that every element in the subsequence is formed by multiplying previous element with a prime
Last Updated :
15 Nov, 2023
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
Brute Force Approach: The brute force approach for solving the problem of finding the length of the longest subsequence in an array where each element is a factor of the next element and the quotient is a prime number involves iterating over the array and for each element, iterating over all the elements after it to find the elements that are multiples of the current element and have a prime quotient. If such an element is found, the length of the subsequence starting from the current element is updated by adding 1 to the length of the subsequence starting from the element that satisfies the condition. The maximum length of all such subsequences is then returned as the answer.
- Initialize an array dp with all values set to 0.
- Initialize dp[n-1] to 1 since the last element is always part of the subsequence.
- Iterate over the array from the second last element to the first element.
- For each element, iterate over all the elements after it and check if the current element is a divisor of the next element and if the quotient is a prime number.
- If both conditions are true, update the value of dp[i] with the maximum of dp[j] (where j is the index of the element that satisfies the conditions).
- Once all the iterations are complete, find the maximum value in the dp array and return it as the answer.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
// Function to check if a number is prime or not
bool isPrime(int num)
{
if (num <= 1)
return false;
for (int i = 2; i * i <= num; i++) {
if (num % i == 0)
return false;
}
return true;
}
// Function to find the longest subsequence
int findLongest(int A[], int n)
{
// Initialize the dp array with all values set to 0
int dp[n];
memset(dp, 0, sizeof dp);
// Initialize dp[n-1] to 1 since the last element is
// always part of the subsequence
dp[n - 1] = 1;
// Iterate over the array from the second last element
// to the first element
for (int i = n - 2; i >= 0; i--) {
// Get the current element
int num = A[i];
// Initialize dp[i] to 1 as the current element is
// always part of the subsequence
dp[i] = 1;
// Initialize maxi to 0
int maxi = 0;
// Iterate over all the elements after i and check
// if the current element is a divisor of the next
// element and if the quotient is a prime number
for (int j = i + 1; j < n; j++) {
if (A[j] % num == 0 && isPrime(A[j] / num)) {
// If both conditions are true, update maxi
// with the maximum value of dp[j]
maxi = max(maxi, dp[j]);
}
}
// Update dp[i] with dp[j] + 1
dp[i] += maxi;
}
// Find the maximum value in the dp array and return it
// as the answer
int ans = 1;
for (int i = 0; i < n; i++) {
ans = max(ans, dp[i]);
}
return ans;
}
int main()
{
int a[] = { 1, 2, 5, 6, 12, 35, 60, 385 };
int n = sizeof(a) / sizeof(a[0]);
cout << findLongest(a, n);
return 0;
}
Java
import java.util.Arrays;
public class Main {
// Function to check if a number is prime or not
static boolean isPrime(int num)
{
if (num <= 1)
return false;
for (int i = 2; i * i <= num; i++) {
if (num % i == 0)
return false;
}
return true;
}
// Function to find the longest subsequence
static int findLongest(int[] A, int n)
{
// Initialize the dp array with all values set to 0
int[] dp = new int[n];
Arrays.fill(dp, 0);
// Initialize dp[n-1] to 1 since the last element is
// always part of the subsequence
dp[n - 1] = 1;
// Iterate over the array from the second last
// element to the first element
for (int i = n - 2; i >= 0; i--) {
// Get the current element
int num = A[i];
// Initialize dp[i] to 1 as the current element
// is always part of the subsequence
dp[i] = 1;
// Initialize maxi to 0
int maxi = 0;
// Iterate over all the elements after i and
// check if the current element is a divisor of
// the next element and if the quotient is a
// prime number
for (int j = i + 1; j < n; j++) {
if (A[j] % num == 0
&& isPrime(A[j] / num)) {
// If both conditions are true, update
// maxi with the maximum value of dp[j]
maxi = Math.max(maxi, dp[j]);
}
}
// Update dp[i] with dp[j] + 1
dp[i] += maxi;
}
// Find the maximum value in the dp array and return
// it as the answer
int ans = 1;
for (int i = 0; i < n; i++) {
ans = Math.max(ans, dp[i]);
}
return ans;
}
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));
}
}
Python3
# Function to check if a number is prime or not
def is_prime(num):
if num <= 1:
return False
for i in range(2, int(num**0.5) + 1):
if num % i == 0:
return False
return True
# Function to find the longest subsequence
def find_longest(A):
n = len(A)
# Initialize the dp list with all values set to 0
dp = [0] * n
# Initialize dp[n-1] to 1 since the last element is
# always part of the subsequence
dp[n - 1] = 1
# Iterate over the list from the second last element
# to the first element
for i in range(n - 2, -1, -1):
# Get the current element
num = A[i]
# Initialize dp[i] to 1 as the current element is
# always part of the subsequence
dp[i] = 1
# Initialize maxi to 0
maxi = 0
# Iterate over all the elements after i and check
# if the current element is a divisor of the next
# element and if the quotient is a prime number
for j in range(i + 1, n):
if A[j] % num == 0 and is_prime(A[j] // num):
# If both conditions are true, update maxi
# with the maximum value of dp[j]
maxi = max(maxi, dp[j])
# Update dp[i] with dp[j] + 1
dp[i] += maxi
# Find the maximum value in the dp list and return it
# as the answer
ans = 1
for i in range(n):
ans = max(ans, dp[i])
return ans
a = [1, 2, 5, 6, 12, 35, 60, 385]
print(find_longest(a))
C#
using System;
class Program
{
// Function to check if a number is prime or not
static bool IsPrime(int num)
{
if (num <= 1)
return false;
for (int i = 2; i * i <= num; i++)
{
if (num % i == 0)
return false;
}
return true;
}
// Function to find the longest subsequence
static int FindLongest(int[] A, int n)
{
// Initialize the dp array with all values set to 0
int[] dp = new int[n];
Array.Clear(dp, 0, n);
// Initialize dp[n-1] to 1 since the last element is always part of the subsequence
dp[n - 1] = 1;
// Iterate over the array from the second last element to the first element
for (int i = n - 2; i >= 0; i--)
{
// Get the current element
int num = A[i];
// Initialize dp[i] to 1 as the current element is always part of the subsequence
dp[i] = 1;
// Initialize maxi to 0
int maxi = 0;
// Iterate over all the elements after i and check if the current element is a divisor of the next
// element and if the quotient is a prime number
for (int j = i + 1; j < n; j++)
{
if (A[j] % num == 0 && IsPrime(A[j] / num))
{
// If both conditions are true, update maxi with the maximum value of dp[j]
maxi = Math.Max(maxi, dp[j]);
}
}
// Update dp[i] with dp[j] + 1
dp[i] += maxi;
}
// Find the maximum value in the dp array and return it as the answer
int ans = 1;
for (int i = 0; i < n; i++)
{
ans = Math.Max(ans, dp[i]);
}
return ans;
}
static void Main()
{
int[] a = { 1, 2, 5, 6, 12, 35, 60, 385 };
int n = a.Length;
Console.WriteLine(FindLongest(a, n));
}
}
JavaScript
// Function to check if a number is prime or not
function isPrime(num) {
if (num <= 1) {
return false;
}
for (let i = 2; i * i <= num; i++) {
if (num % i === 0) {
return false;
}
}
return true;
}
// Function to find the longest subsequence
function findLongest(A) {
const n = A.length;
// Initialize the dp array with all values set to 0
const dp = new Array(n).fill(0);
// Initialize dp[n-1] to 1 since the last element is always part of the subsequence
dp[n - 1] = 1;
// Iterate over the array from the second last element to the first element
for (let i = n - 2; i >= 0; i--) {
// Get the current element
const num = A[i];
// Initialize dp[i] to 1 as the current element is always part of the subsequence
dp[i] = 1;
// Initialize maxi to 0
let maxi = 0;
// Iterate over all the elements after i and check if the current element is a divisor
// of the next element and if the quotient is a prime number
for (let j = i + 1; j < n; j++) {
if (A[j] % num === 0 && isPrime(A[j] / num)) {
// If both conditions are true, update maxi with the maximum value of dp[j]
maxi = Math.max(maxi, dp[j]);
}
}
// Update dp[i] with dp[j] + 1
dp[i] += maxi;
}
// Find the maximum value in the dp array and return it as the answer
let ans = 1;
for (let i = 0; i < n; i++) {
ans = Math.max(ans, dp[i]);
}
return ans;
}
// Example usage
const a = [1, 2, 5, 6, 12, 35, 60, 385];
console.log(findLongest(a));
Output:
5
Time Complexity: O(N * N)
Auxiliary Space: O(N)
Efficient 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>
Time Complexity: O(N log N)
Auxiliary Space: O(N)
Similar Reads
Maximum length subsequence such that adjacent elements in the subsequence have a common factor
Given an array arr[], the task is to find the maximum length of a subsequence such that the adjacent elements in the subsequence have a common factor. Examples: Input: arr[] = { 13, 2, 8, 6, 3, 1, 9 } Output: 5Max length subsequence with satisfied conditions: { 2, 8, 6, 3, 9 } Input: arr[] = { 12, 2
9 min read
Minimum sum subsequence such that at least one of every four consecutive elements is picked
Given an array arr[] of positive integers. The task is to find minimum sum subsequence from the array such that at least one value among all groups of four consecutive elements is picked. Examples : Input: arr[] = {1, 2, 3, 4, 5, 6, 7, 8}Output: 66 is sum of output subsequence {1, 5}Note that we hav
15+ min read
Length of longest subsequence such that prefix sum at every element remains greater than zero
Given an array arr[] of size N and an integer X, the task is to find the length of the longest subsequence such that the prefix sum at every element of the subsequence remains greater than zero. Example: Input: arr[] = {-2, -1, 1, 2, -2}, N = 5Output: 3Explanation: The sequence can be made of elemen
6 min read
Maximize subsequences having array elements not exceeding length of the subsequence
Given an array arr[] consisting of N positive integers, the task is to maximize the number of subsequences that can be obtained from an array such that every element arr[i] that is part of any subsequence does not exceed the length of that subsequence. Examples: Input: arr[] = {1, 1, 1, 1} Output: 4
6 min read
Generate longest possible array with product K such that each array element is divisible by its previous adjacent element
Given an integer K, the task is to construct an array of maximum length with product of all array elements equal to K, such that each array element except the first one is divisible by its previous adjacent element.Note: Every array element in the generated array must be greater than 1. Examples: In
7 min read
Count subsequences for every array element in which they are the maximum
Given an array arr[] consisting of N unique elements, the task is to generate an array B[] of length N such that B[i] is the number of subsequences in which arr[i] is the maximum element. Examples: Input: arr[] = {2, 3, 1}Output: {2, 4, 1}Explanation: Subsequences in which arr[0] ( = 2) is maximum a
11 min read
Longest subsequence with first and last element greater than all other elements
Given a permutation from 1 to N of size N. Find the length of the longest subsequence having the property that the first and last element is greater than all the other subsequence elements. Examples: Input : N = 6 4 2 6 5 3 1 Output : 3 The subsequence that has the longest size is [4, 2, 3] or [4, 2
15 min read
Longest Subsequence with at least one common digit in every element
Given an array. The task is to find the length of the longest subsequence in which all elements must have at least one digit in common. Examples: Input : arr[] = { 11, 12, 23, 74, 13 } Output : 3 Explanation: The elements 11, 12, and 13 have the digit '1' as common. So it is the required longest sub
9 min read
Length of the longest subsequence such that XOR of adjacent elements is equal to K
Given an array arr[] of N non-negative integers and an integer K, the idea is to find the length of the longest subsequence having Xor of adjacent elements equal to K. Examples: Input: N = 5, arr[] = {3, 2, 4, 3, 5}, K = 1Output: 3Explanation:All the subsequences having Xor of adjacent element equal
13 min read
Queries to find longest subsequence having no similar adjacent elements with updates
Given an array arr[] consisting of N integers and an array Queries[][] with each query of the form {x, y}. For each query, the task is to replace the element at index x ( 1-based indexing ) by y and find the length of the longest subsequence having no similar adjacent elements. Examples: Input: arr[
14 min read