Largest subsequence such that all indices and all values are multiples individually

Given an array arr[] of N positive integers, the task is to find the largest strictly increasing subsequence of arr[] such that the indices of the selected elements in arr[], and the selected elements are multiples of each other individually.
Note: Consider 1 based indexing for the array arr[].

Examples:

Input: arr[] = {1, 4, 2, 3, 6, 4, 9}
Output: 3
Explanation:
We can choose index 1, 3, 6 and values are 1, 2, 4:
Here every greater index is divisible by smaller index and every greater index value is greater than the smaller index value.

Input: arr[] = {5, 3, 4, 6}
Output: 2
Explanation:
We can choose index 1 and 3 and values are 3 and 6:
Here, every greater index is divisible by smaller index and every greater index value is greater than the smaller index value.

Naive Approach:
The naive approach is to simply generate all possible subsequence and for each subsequence check two conditions:



  • first check if elements are in strictly increasing order and
  • secondly check if the index of the selected elements in arr[] is multiple of each other.

Out of all possible subsequence which satisfies the given two conditions select the largest subsequence.
Time Complexity: O( N * 2N )
Auxiliary Space: O( N )

Efficient Approach:
We can optimize the code by using Dynamic Programming by avoiding redundant calculation of the repeated sub problem by caching its result.

  1. Create an array dp[] of size equal to the size of arr[], where dp[i] represents size of largest subsequence till i-th index which satisfies the given conditions.
  2. Initialize array dp[] with 0.
  3. Now, iterate the array arr[] from the end.
  4. For each index find the indices j which divide the current index and check if the value at current index is greater than the element at index j.
  5. If it is then update dp[j] as:

    dp[j] = max(dp[current] + 1, dp[j])

  6. Finally, traverse the array dp[] and print the maximum value.

Below is the implementation of the efficient approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
  
// Function that print maximum length
// of array
void maxLength(int arr[], int n)
{
    // dp[] array to store the
    // maximum length
    vector<int> dp(n, 1);
  
    for (int i = n - 1; i > 1; i--) {
  
        // Find all divisors of i
        for (int j = 1;
             j <= sqrt(i); j++) {
  
            if (i % j == 0) {
                int s = i / j;
  
                if (s == j) {
  
                    // If the current value
                    // is greater than the
                    // divisor's value
                    if (arr[i] > arr[s]) {
  
                        dp[s] = max(dp[i] + 1,
                                    dp[s]);
                    }
                }
                else {
  
                    // If current value
                    // is greater
                    // than the divisor's value
                    // and s is not equal
                    // to current index
                    if (s != i
                        && arr[i] > arr[s])
                        dp[s] = max(dp[i] + 1,
                                    dp[s]);
  
                    // Condition if current
                    // value is greater
                    // than the divisor's value
                    if (arr[i] > arr[j]) {
                        dp[j] = max(dp[i] + 1,
                                    dp[j]);
                    }
                }
            }
        }
    }
  
    int max = 0;
  
    // Computing the greatest value
    for (int i = 1; i < n; i++) {
        if (dp[i] > max)
            max = dp[i];
    }
  
    // Printing maximum length of array
    cout << max << "\n";
}
  
// Driver Code
int main()
{
    // Given array arr[]
    int arr[] = { 0, 1, 4, 2, 3, 6, 4, 9 };
    int size = sizeof(arr) / sizeof(arr[0]);
  
    // Function Call
    maxLength(arr, size);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for the above approach 
import java.util.*;
import java.io.*;
  
class GFG{ 
      
// Function that print maximum length
// of array
static void maxLength(int arr[], int n)
{
      
    // dp[] array to store the
    // maximum length
    int dp[] = new int[n];
    for(int i = 1; i < n; i++)
    {
        dp[i] = 1;
    }
  
    for(int i = n - 1; i > 1; i--) 
    {
          
        // Find all divisors of i
        for(int j = 1;
                j <= Math.sqrt(i); j++)
        {
            if (i % j == 0
            {
                int s = i / j;
  
                if (s == j)
                {
                      
                    // If the current value
                    // is greater than the
                    // divisor's value
                    if (arr[i] > arr[s]) 
                    {
                        dp[s] = Math.max(dp[i] + 1,
                                         dp[s]);
                    }
                }
                else 
                {
                      
                    // If current value is greater
                    // than the divisor's value
                    // and s is not equal
                    // to current index
                    if (s != i && arr[i] > arr[s])
                        dp[s] = Math.max(dp[i] + 1,
                                         dp[s]);
      
                    // Condition if current
                    // value is greater
                    // than the divisor's value
                    if (arr[i] > arr[j])
                    {
                        dp[j] = Math.max(dp[i] + 1,
                                         dp[j]);
                    }
                }
            }
        }
    }
    int max = 0;
  
    // Computing the greatest value
    for(int i = 1; i < n; i++) 
    {
        if (dp[i] > max)
            max = dp[i];
    }
      
    // Printing maximum length of array
    System.out.println(max);
}
  
// Driver Code
public static void main(String[] args)
{
      
    // Given array arr[]
    int arr[] = { 0, 1, 4, 2, 3, 6, 4, 9 };
    int size = arr.length;
  
    // Function call
    maxLength(arr, size);
}
}
  
// This code is contributed by sanjoy_62

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program for the above approach
from math import *
  
# Function that print maximum length 
# of array
def maxLength (arr, n):
  
    # dp[] array to store the 
    # maximum length 
    dp = [1] * n
  
    for i in range(n - 1, 1, -1):
  
        # Find all divisors of i
        for j in range(1, int(sqrt(i)) + 1):
            if (i % j == 0):
                s = i // j
  
                if (s == j):
  
                    # If the current value 
                    # is greater than the 
                    # divisor's value
                    if (arr[i] > arr[s]):
                        dp[s] = max(dp[i] + 1, dp[s])
  
                else:
                    # If current value 
                    # is greater 
                    # than the divisor's value 
                    # and s is not equal 
                    # to current index 
                    if (s != i and arr[i] > arr[s]):
                        dp[s] = max(dp[i] + 1, dp[s])
  
                    # Condition if current 
                    # value is greater 
                    # than the divisor's value
                    if (arr[i] > arr[j]):
                        dp[j] = max(dp[i] + 1, dp[j])
  
    Max = 0
  
    # Computing the greatest value
    for i in range(1, n):
        if (dp[i] > Max):
            Max = dp[i]
  
    # Printing maximum length of array
    print(Max)
  
# Driver Code
if __name__ == '__main__':
  
    # Given array arr[]
    arr = [ 0, 1, 4, 2, 3, 6, 4, 9]
    size = len(arr)
  
    # Function call
    maxLength(arr, size)
  
# This code is contributed by himanshu77

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program for the above approach 
using System;
  
class GFG{ 
  
// Function that print maximum length
// of array
static void maxLength(int[] arr, int n)
{
      
    // dp[] array to store the
    // maximum length
    int[] dp = new int[n];
    for(int i = 1; i < n; i++)
    {
        dp[i] = 1;
    }
  
    for(int i = n - 1; i > 1; i--)
    {
          
        // Find all divisors of i
        for(int j = 1;
                j <= Math.Sqrt(i); j++)
        {
            if (i % j == 0)
            {
                int s = i / j;
                  
                if (s == j) 
                {
                      
                    // If the current value
                    // is greater than the
                    // divisor's value
                    if (arr[i] > arr[s]) 
                    {
                        dp[s] = Math.Max(dp[i] + 1,
                                         dp[s]);
                    }
                }
                else 
                {
                      
                    // If current value is greater
                    // than the divisor's value
                    // and s is not equal
                    // to current index
                    if (s != i && arr[i] > arr[s])
                        dp[s] = Math.Max(dp[i] + 1,
                                         dp[s]);
      
                    // Condition if current
                    // value is greater
                    // than the divisor's value
                    if (arr[i] > arr[j]) 
                    {
                        dp[j] = Math.Max(dp[i] + 1,
                                         dp[j]);
                    }
                }
            }
        }
    }
    int max = 0;
  
    // Computing the greatest value
    for(int i = 1; i < n; i++) 
    {
        if (dp[i] > max)
            max = dp[i];
    }
  
    // Printing maximum length of array
    Console.WriteLine(max);
}
  
// Driver Code
public static void Main()
{
      
    // Given array arr[]
    int[] arr = new int[] { 0, 1, 4, 2, 
                            3, 6, 4, 9 };
    int size = arr.Length;
  
    // Function call
    maxLength(arr, size);
}
}
  
// This code is contributed by sanjoy_62

chevron_right


Output:

3

Time Complexity: O(N*(sqrt(N)) Since, for each index of the array, we calculate its all divisor, this takes O(sqrt(N))
Auxiliary Space: O(N)

competitive-programming-img




My Personal Notes arrow_drop_up

Recommended Posts:


Check out this Author's contributed articles.

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.