Given an array arr[] of size N. The task is to find the length of the longest subsequence from the given array such that the sequence is strictly increasing and no two adjacent elements are coprime.
Note: The elements in the given array are strictly increasing in order (1 <= a[i] <= 105)
Examples:
Input : a[] = { 1, 2, 3, 4, 5, 6}
Output : 3
Explanation : Possible sub sequences are {1}, {2}, {3}, {4}, {5}, {6}, {2, 4}, {2, 4, 6}, {2, 6}, {4, 6}, {3, 6}.
The subsequence {2, 4, 6} has the longest length.
Input : a[] = { 1, 1, 1, 1}
Output : 1
Approach: The main idea is to use the concept of Dynamic programming. Let’s define dp[x] as the maximal value of the length of the subsequence whose last element is x, and define d[i] as the (maximal value of dp[x] where x is divisible by i).
We should calculate dp[x] in the increasing order of x. The value of dp[x] is (maximal value of d[i] where i is a divisor of x) + 1. After we calculate dp[x], for each divisor i of x, we should update d[i] too. This algorithm works in O(N*logN) because the sum of the number of the divisors from 1 to N is O(N*logN).
Note: There is a corner case. When the set is {1}, you should output 1.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
#define N 100005
int LIS( int a[], int n)
{
int dp[N], d[N];
int ans = 0;
for ( int i = 0; i < n; i++) {
dp[a[i]] = 1;
for ( int j = 2; j * j <= a[i]; j++) {
if (a[i] % j == 0) {
dp[a[i]] = max(dp[a[i]], dp[d[j]] + 1);
dp[a[i]] = max(dp[a[i]], dp[d[a[i] / j]] + 1);
d[j] = a[i];
d[a[i] / j] = a[i];
}
}
ans = max(ans, dp[a[i]]);
d[a[i]] = a[i];
}
return ans;
}
int main()
{
int a[] = { 1, 2, 3, 4, 5, 6 };
int n = sizeof (a) / sizeof (a[0]);
cout << LIS(a, n);
return 0;
}
|
Java
class GFG
{
static int N= 100005 ;
static int LIS( int a[], int n)
{
int dp[]= new int [N], d[]= new int [N];
int ans = 0 ;
for ( int i = 0 ; i < n; i++)
{
dp[a[i]] = 1 ;
for ( int j = 2 ; j * j <= a[i]; j++)
{
if (a[i] % j == 0 )
{
dp[a[i]] = Math.max(dp[a[i]], dp[d[j]] + 1 );
dp[a[i]] = Math.max(dp[a[i]], dp[d[a[i] / j]] + 1 );
d[j] = a[i];
d[a[i] / j] = a[i];
}
}
ans = Math.max(ans, dp[a[i]]);
d[a[i]] = a[i];
}
return ans;
}
public static void main(String args[])
{
int a[] = { 1 , 2 , 3 , 4 , 5 , 6 };
int n = a.length;
System.out.print( LIS(a, n));
}
}
|
Python3
N = 100005
def LIS(a, n):
dp = [ 0 for i in range (N)]
d = [ 0 for i in range (N)]
ans = 0
for i in range (n):
dp[a[i]] = 1
for j in range ( 2 , a[i]):
if j * j > a[i]:
break
if (a[i] % j = = 0 ):
dp[a[i]] = max (dp[a[i]],
dp[d[j]] + 1 )
dp[a[i]] = max (dp[a[i]],
dp[d[a[i] / / j]] + 1 )
d[j] = a[i]
d[a[i] / / j] = a[i]
ans = max (ans, dp[a[i]])
d[a[i]] = a[i]
return ans
a = [ 1 , 2 , 3 , 4 , 5 , 6 ]
n = len (a)
print (LIS(a, n))
|
C#
using System;
class GFG
{
static int N = 100005;
static int LIS( int []a, int n)
{
int []dp = new int [N];
int []d = new int [N];
int ans = 0;
for ( int i = 0; i < n; i++)
{
dp[a[i]] = 1;
for ( int j = 2; j * j <= a[i]; j++)
{
if (a[i] % j == 0)
{
dp[a[i]] = Math.Max(dp[a[i]], dp[d[j]] + 1);
dp[a[i]] = Math.Max(dp[a[i]], dp[d[a[i] / j]] + 1);
d[j] = a[i];
d[a[i] / j] = a[i];
}
}
ans = Math.Max(ans, dp[a[i]]);
d[a[i]] = a[i];
}
return ans;
}
public static void Main()
{
int []a = { 1, 2, 3, 4, 5, 6 };
int n = a.Length;
Console.WriteLine(LIS(a, n));
}
}
|
PHP
<?php
$N = 100005;
function LIS( $a , $n )
{
$dp = array ();
$d = array ();
$ans = 0;
for ( $i = 0; $i < $n ; $i ++)
{
$dp [ $a [ $i ]] = 1;
for ( $j = 2; $j * $j <= $a [ $i ]; $j ++)
{
if ( $a [ $i ] % $j == 0)
{
$dp [ $a [ $i ]] = max( $dp [ $a [ $i ]],
$dp [ $d [ $j ]] + 1);
$dp [ $a [ $i ]] = max( $dp [ $a [ $i ]],
$dp [ $d [ $a [ $i ] / $j ]] + 1);
$d [ $j ] = $a [ $i ];
$d [ $a [ $i ] / $j ] = $a [ $i ];
}
}
$ans = max( $ans , $dp [ $a [ $i ]]);
$d [ $a [ $i ]] = $a [ $i ];
}
return $ans ;
}
$a = array (1, 2, 3, 4, 5, 6);
$n = sizeof( $a );
echo LIS( $a , $n );
?>
|
Javascript
<script>
let N = 100005;
function LIS(a, n)
{
let dp = new Array();
let d = new Array();
let ans = 0;
for (let i = 0; i < n; i++)
{
dp[a[i]] = 1;
for (j = 2; j * j <= a[i]; j++)
{
if (a[i] % j == 0)
{
dp[a[i]] = Math.max(dp[a[i]],
dp[d[j]] + 1);
dp[a[i]] = Math.max(dp[a[i]],
dp[d[a[i] / j]] + 1);
d[j] = a[i];
d[a[i] / j] = a[i];
}
}
ans = Math.max(ans, dp[a[i]]);
d[a[i]] = a[i];
}
return ans;
}
let a = [1, 2, 3, 4, 5, 6];
let n = a.length;
document.write(LIS(a, n));
</script>
|
Time Complexity: O(N* log(N))
Auxiliary Space: O(N), since N extra space has been taken.