# 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[] = { 1, 2, 2, 3, 3, 1 }

Output:2

**Approach:** A **naive** approach is to consider all subsequences and check every subsequence whether it satisfies the condition.

An **efficient** solution is to use **Dynamic programming**. Let dp[i] denote the maximum length of subsequence including arr[i]. Then, the following relation holds for every prime p such that p is a prime factor of arr[i]:

dp[i] = max(dp[i], 1 + dp[pos[p]]) where pos[p] gives the index of p in the array where it last occurred.

**Explanation:** Traverse the array. For an element arr[i], there are 2 possibilities.

- If the prime factors of arr[i] have shown their first appearance in the array, then dp[i] = 1
- If the prime factors of arr[i] have already occurred, then this element can be added in the subsequence since there’s a common factor. Hence dp[i] = max(dp[i], 1 + dp[pos[p]]) where p is the common prime factor and pos[p] is the latest index of p in the array.

Below is the implementation of the above approach:

## C++

`// C++ implementation of the above approach ` `#include <bits/stdc++.h> ` `#define N 100005 ` `#define MAX 10000002 ` ` ` `using` `namespace` `std; ` ` ` `int` `lpd[MAX]; ` ` ` `// to compute least prime divisor of i ` `void` `preCompute() ` `{ ` ` ` `memset` `(lpd, 0, ` `sizeof` `(lpd)); ` ` ` `lpd[0] = lpd[1] = 1; ` ` ` `for` `(` `int` `i = 2; i * i < MAX; i++) { ` ` ` `for` `(` `int` `j = i * 2; j < MAX; j += i) { ` ` ` `if` `(lpd[j] == 0) { ` ` ` `lpd[j] = i; ` ` ` `} ` ` ` `} ` ` ` `} ` ` ` `for` `(` `int` `i = 2; i < MAX; i++) { ` ` ` `if` `(lpd[i] == 0) { ` ` ` `lpd[i] = i; ` ` ` `} ` ` ` `} ` `} ` ` ` `// Function that returns the maximum ` `// length subsequence such that ` `// adjacent elements have a common factor. ` `int` `maxLengthSubsequence(` `int` `arr[], ` `int` `n) ` `{ ` ` ` `int` `dp[N]; ` ` ` `unordered_map<` `int` `, ` `int` `> pos; ` ` ` ` ` `// Initialize dp array with 1. ` ` ` `for` `(` `int` `i = 1; i <= n; i++) ` ` ` `dp[i] = 1; ` ` ` ` ` `for` `(` `int` `i = 1; i <= n; i++) { ` ` ` `while` `(arr[i] > 1) { ` ` ` `int` `p = lpd[arr[i]]; ` ` ` `if` `(pos[p]) { ` ` ` `// p has appeared at least once. ` ` ` `dp[i] = max(dp[i], 1 + dp[pos[p]]); ` ` ` `} ` ` ` `// Update latest occurence of prime p. ` ` ` `pos[p] = i; ` ` ` `while` `(arr[i] % p == 0) ` ` ` `arr[i] /= p; ` ` ` `} ` ` ` `} ` ` ` ` ` `// Take maximum value as the answer. ` ` ` `int` `ans = 1; ` ` ` `for` `(` `int` `i = 1; i <= n; i++) { ` ` ` `ans = max(ans, dp[i]); ` ` ` `} ` ` ` ` ` `return` `ans; ` `} ` ` ` `// Driver code ` `int` `main() ` `{ ` ` ` `int` `arr[] = { 13, 2, 8, 6, 3, 1, 9 }; ` ` ` `int` `n = ` `sizeof` `(arr) / ` `sizeof` `(arr[0]); ` ` ` ` ` `preCompute(); ` ` ` ` ` `cout << maxLengthSubsequence(arr, n); ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

## Python3

# Python3 implementation of the

# above approach

import math as mt

N = 100005

MAX = 1000002

lpd = [0 for i in range(MAX)]

# to compute least prime divisor of i

def preCompute():

lpd[0], lpd[1] = 1, 1

for i in range(2, mt.ceil(mt.sqrt(MAX))):

for j in range(2 * i, MAX, i):

if (lpd[j] == 0):

lpd[j] = i

for i in range(2, MAX):

if (lpd[i] == 0):

lpd[i] = i

# Function that returns the maximum

# length subsequence such that

# adjacent elements have a common factor.

def maxLengthSubsequence(arr, n):

dp = [1 for i in range(N + 1)]

pos = dict()

# Initialize dp array with 1.

for i in range(1, n):

while (arr[i] > 1):

p = lpd[arr[i]]

if (p in pos.keys()):

# p has appeared at least once.

dp[i] = max(dp[i], 1 + dp[pos[p]])

# Update latest occurence of prime p.

pos[p] = i

while (arr[i] % p == 0):

arr[i] //= p

# Take maximum value as the answer.

ans = 1

for i in range(1, n + 1):

ans = max(ans, dp[i])

return ans

# Driver code

arr = [13, 2, 8, 6, 3, 1, 9]

n = len(arr)

preCompute()

print(maxLengthSubsequence(arr, n))

# This code is contributed by Mohit Kumar

## Java

`// Java implementation of the above approach ` `import` `java.util.*; ` `class` `GfG ` `{ ` ` ` `static` `int` `N = ` `100005` `; ` `static` `int` `MAX = ` `10000002` `; ` ` ` ` ` ` ` `static` `int` `lpd[] = ` `new` `int` `[MAX]; ` ` ` `// to compute least prime divisor of i ` `static` `void` `preCompute() ` `{ ` ` ` `lpd[` `0` `] = lpd[` `1` `] = ` `1` `; ` ` ` `for` `(` `int` `i = ` `2` `; i * i < MAX; i++) ` ` ` `{ ` ` ` `for` `(` `int` `j = i * ` `2` `; j < MAX; j += i) ` ` ` `{ ` ` ` `if` `(lpd[j] == ` `0` `) ` ` ` `{ ` ` ` `lpd[j] = i; ` ` ` `} ` ` ` `} ` ` ` `} ` ` ` `for` `(` `int` `i = ` `2` `; i < MAX; i++) ` ` ` `{ ` ` ` `if` `(lpd[i] == ` `0` `) ` ` ` `{ ` ` ` `lpd[i] = i; ` ` ` `} ` ` ` `} ` `} ` ` ` `// Function that returns the maximum ` `// length subsequence such that ` `// adjacent elements have a common factor. ` `static` `int` `maxLengthSubsequence(` `int` `arr[], ` `int` `n) ` `{ ` ` ` `int` `dp[] = ` `new` `int` `[N]; ` `Map<Integer, Integer> pos = ` `new` `HashMap<Integer, Integer> (); ` ` ` ` ` `// Initialize dp array with 1. ` ` ` `for` `(` `int` `i = ` `1` `; i <= n; i++) ` ` ` `dp[i] = ` `1` `; ` ` ` ` ` `for` `(` `int` `i = ` `1` `; i <= n; i++) ` ` ` `{ ` ` ` `while` `(arr[i] > ` `1` `) ` ` ` `{ ` ` ` `int` `p = lpd[arr[i]]; ` ` ` `if` `(pos.containsKey(p)) ` ` ` `{ ` ` ` `// p has appeared at least once. ` ` ` `dp[i] = Math.max(dp[i], ` `1` `+ dp[pos.get(p)]); ` ` ` `} ` ` ` ` ` `// Update latest occurence of prime p. ` ` ` `pos.put(p, i); ` ` ` `while` `(arr[i] % p == ` `0` `) ` ` ` `arr[i] /= p; ` ` ` `} ` ` ` `} ` ` ` ` ` `// Take maximum value as the answer. ` ` ` `int` `ans = ` `1` `; ` ` ` `for` `(` `int` `i = ` `1` `; i <= n; i++) ` ` ` `{ ` ` ` `ans = Math.max(ans, dp[i]); ` ` ` `} ` ` ` ` ` `return` `ans; ` `} ` ` ` `// Driver code ` `public` `static` `void` `main(String[] args) ` `{ ` ` ` `int` `arr[] = { ` `13` `, ` `2` `, ` `8` `, ` `6` `, ` `3` `, ` `1` `, ` `9` `}; ` ` ` `int` `n = arr.length - ` `1` `; ` ` ` ` ` `preCompute(); ` ` ` `System.out.println(maxLengthSubsequence(arr, n)); ` `} ` `} ` ` ` `// This code is contributed by Prerna Saini. ` |

*chevron_right*

*filter_none*

**Output:**

5

## Recommended Posts:

- Maximum length subsequence with difference between adjacent elements as either 0 or 1
- Length of longest common subsequence containing vowels
- Minimum cost to make Longest Common Subsequence of length k
- Find the Increasing subsequence of length three with maximum product
- Maximum sum subsequence with at-least k distant elements
- Longest Common Subsequence | DP-4
- Longest Common Subsequence with at most k changes allowed
- Longest Common Subsequence | DP using Memoization
- Count common subsequence in two strings
- LCS (Longest Common Subsequence) of three strings
- Longest Common Increasing Subsequence (LCS + LIS)
- C++ Program for Longest Common Subsequence
- Longest Subsequence with at least one common digit in every element
- Edit distance and LCS (Longest Common Subsequence)
- Python Program for Longest Common Subsequence

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.