# 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.

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

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++ program for the above approach ` `#include ` `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); ` ` `  `    ``// Function Call ` `    ``maxLength(arr, size); ` `    ``return` `0; ` `} `

 `// 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 `

 `# 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 `

 `// 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 `

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)

Interns at Geeksforgeeks

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 : sanjoy_62, himanshu77, nidhi_biet