# Subsequence X of length K such that gcd(X, X) + (X, X) + … is maximized

Given an array a of size N. The task is to find a subsequence X of length K such that gcd(X, X) + (X, X) + … is maximimum.

Note: K is even.

Examples:

Input: a[] = {4, 5, 3, 7, 8, 10, 9, 8}, k = 4
Output: 9
The subsequence {4, 7, 8, 8} gives the maximum value = 9.
Other subsequences like { 5, 3, 8, 8} also gives 9.

Input: a[] = {5, 8, 16, 20}, K = 2
Output:
The subsequence {8, 16} gives the maximum value.

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

Naive Approach: A naive approach is to generate all subsequences of length K using recursion and find the maximum value possible.

Efficient Approach: An efficient approach is to use Dynamic Programming to solve the above problem. Let dp[i][j] denote the value of the pair gcd sum if i-th index element is taken as the j-th element. Recursively generate all subsequences possible. If cnt of elements taken is odd then add gcd(a[prev], a[current]) to the sum since this number will be the second in the pair and recur for next element. If cnt is even, then simply recur setting a[i] as the previous element. Memoization has been used to avoid re-calculation of the same recurrence. The maximum of all the generated sums will be the answer.

Below is the implementation of the above approach:

## C++

 `// C++ program to find the sum of ` `// the addition of all possible subsets ` `#include ` `using` `namespace` `std; ` `const` `int` `MAX = 100; ` ` `  `// Recursive function to find the maximum value of ` `// the given recurrence ` `int` `recur(``int` `ind, ``int` `cnt, ``int` `last, ``int` `a[], ` `          ``int` `n, ``int` `k, ``int` `dp[][MAX]) ` `{ ` ` `  `    ``// If we get K elements ` `    ``if` `(cnt == k) ` `        ``return` `0; ` ` `  `    ``// If we have reached the end ` `    ``// and K elements are not there ` `    ``if` `(ind == n) ` `        ``return` `-1e9; ` ` `  `    ``// If the state has been visited ` `    ``if` `(dp[ind][cnt] != -1) ` `        ``return` `dp[ind][cnt]; ` `    ``int` `ans = 0; ` ` `  `    ``// Iterate for every element as the ` `    ``// next possible element ` `    ``// and take the element which gives ` `    ``// the maximum answer ` `    ``for` `(``int` `i = ind; i < n; i++)  ` `    ``{ ` `        ``// If this element is the first element ` `        ``// in the individual pair in the subsequence ` `        ``// then simply recurrence with the last ` `        ``// element as i-th index ` `        ``if` `(cnt % 2 == 0) ` `         ``ans=max(ans,recur(i + 1, cnt + 1, i, a, n, k, dp)); ` ` `  `        ``// If this element is the second element in ` `        ``// the individual pair, the find gcd with ` `        ``// the previous element and add to the answer ` `        ``// and recur for the next element ` `        ``else` `            ``ans = max(ans, __gcd(a[last], a[i]) +  ` `                ``recur(i + 1, cnt + 1, 0, a, n, k, dp)); ` `    ``} ` ` `  `    ``return` `dp[ind][cnt] = ans; ` `} ` ` `  `// Driver Code ` `int` `main() ` `{ ` `    ``int` `a[] = { 4, 5, 3, 7, 8, 10, 9, 8 }; ` `    ``int` `n = ``sizeof``(a) / ``sizeof``(a); ` `    ``int` `k = 4; ` `    ``int` `dp[n][MAX]; ` `    ``memset``(dp, -1, ``sizeof` `dp); ` ` `  `    ``cout << recur(0, 0, 0, a, n, k, dp); ` `} `

## Java

 `// Java program to find the sum of ` `// the addition of all possible subsets ` `import` `java.util.*; ` ` `  `class` `GFG  ` `{ ` ` `  `static` `int` `MAX = ``100``; ` ` `  `// Recursive function to find the maximum value of ` `// the given recurrence ` `static` `int` `recur(``int` `ind, ``int` `cnt, ``int` `last, ``int` `a[], ` `                            ``int` `n, ``int` `k, ``int` `dp[][]) ` `{ ` ` `  `    ``// If we get K elements ` `    ``if` `(cnt == k) ` `        ``return` `0``; ` ` `  `    ``// If we have reached the end ` `    ``// and K elements are not there ` `    ``if` `(ind == n) ` `        ``return` `(``int``) -1e9; ` ` `  `    ``// If the state has been visited ` `    ``if` `(dp[ind][cnt] != -``1``) ` `        ``return` `dp[ind][cnt]; ` `    ``int` `ans = ``0``; ` ` `  `    ``// Iterate for every element as the ` `    ``// next possible element ` `    ``// and take the element which gives ` `    ``// the maximum answer ` `    ``for` `(``int` `i = ind; i < n; i++)  ` `    ``{ ` `        ``// If this element is the first element ` `        ``// in the individual pair in the subsequence ` `        ``// then simply recurrence with the last ` `        ``// element as i-th index ` `        ``if` `(cnt % ``2` `== ``0``) ` `            ``ans = Math.max(ans,recur(i + ``1``, cnt + ``1``, i, a, n, k, dp)); ` ` `  `        ``// If this element is the second element in ` `        ``// the individual pair, the find gcd with ` `        ``// the previous element and add to the answer ` `        ``// and recur for the next element ` `        ``else` `            ``ans = Math.max(ans, __gcd(a[last], a[i]) +  ` `                ``recur(i + ``1``, cnt + ``1``, ``0``, a, n, k, dp)); ` `    ``} ` ` `  `    ``return` `dp[ind][cnt] = ans; ` `} ` ` `  `static` `int` `__gcd(``int` `a, ``int` `b)  ` `{  ` `    ``if` `(b == ``0``)  ` `        ``return` `a;  ` `    ``return` `__gcd(b, a % b);  ` `     `  `} ` ` `  `// Driver Code ` `public` `static` `void` `main(String[] args) ` `{ ` `    ``int` `a[] = { ``4``, ``5``, ``3``, ``7``, ``8``, ``10``, ``9``, ``8` `}; ` `    ``int` `n = a.length; ` `    ``int` `k = ``4``; ` `    ``int` `[][]dp = ``new` `int``[n][MAX]; ` `    ``for``(``int` `i = ``0``; i < n; i++) ` `    ``{ ` `        ``for``(``int` `j = ``0``; j < MAX; j++) ` `        ``{ ` `            ``dp[i][j] = -``1``; ` `        ``} ` `    ``} ` `    ``System.out.println(recur(``0``, ``0``, ``0``, a, n, k, dp)); ` `    ``} ` `} ` ` `  `// This code is contributed by Rajput-Ji `

## Python3

 `# Python3 program to find the sum of ` `# the addition of all possible subsets ` `from` `math ``import` `gcd as __gcd ` `MAX` `=` `100` ` `  `# Recursive function to find the  ` `# maximum value of the given recurrence ` `def` `recur(ind, cnt, last, a, n, k, dp): ` ` `  `    ``# If we get K elements ` `    ``if` `(cnt ``=``=` `k): ` `        ``return` `0` ` `  `    ``# If we have reached the end ` `    ``# and K elements are not there ` `    ``if` `(ind ``=``=` `n): ` `        ``return` `-``10``*``*``9` ` `  `    ``# If the state has been visited ` `    ``if` `(dp[ind][cnt] !``=` `-``1``): ` `        ``return` `dp[ind][cnt] ` `    ``ans ``=` `0` ` `  `    ``# Iterate for every element as the ` `    ``# next possible element ` `    ``# and take the element which gives ` `    ``# the maximum answer ` `    ``for` `i ``in` `range``(ind, n): ` `         `  `        ``# If this element is the first element ` `        ``# in the individual pair in the subsequence ` `        ``# then simply recurrence with the last ` `        ``# element as i-th index ` `        ``if` `(cnt ``%` `2` `=``=` `0``): ` `            ``ans ``=` `max``(ans, recur(i ``+` `1``, cnt ``+` `1``,  ` `                                 ``i, a, n, k, dp)) ` ` `  `        ``# If this element is the second element in ` `        ``# the individual pair, the find gcd with ` `        ``# the previous element and add to the answer ` `        ``# and recur for the next element ` `        ``else``: ` `            ``ans ``=` `max``(ans, __gcd(a[last], a[i]) ``+`  `                      ``recur(i ``+` `1``, cnt ``+` `1``, ``0``, a, n, k, dp)) ` ` `  `    ``dp[ind][cnt] ``=` `ans ` `    ``return` `ans ` ` `  `# Driver Code ` `a ``=` `[``4``, ``5``, ``3``, ``7``, ``8``, ``10``, ``9``, ``8` `] ` ` `  `n ``=` `len``(a) ` `k ``=` `4``; ` `dp ``=` `[[``-``1` `for` `i ``in` `range``(``MAX``)]  ` `          ``for` `i ``in` `range``(n)] ` ` `  `print``(recur(``0``, ``0``, ``0``, a, n, k, dp)) ` ` `  `# This code is contributed by Mohit Kumar `

## C#

 `// C# program to find the sum of ` `// the addition of all possible subsets ` `using` `System; ` `     `  `class` `GFG  ` `{ ` ` `  `static` `int` `MAX = 100; ` ` `  `// Recursive function to find the maximum value of ` `// the given recurrence ` `static` `int` `recur(``int` `ind, ``int` `cnt, ``int` `last, ``int` `[]a, ` `                            ``int` `n, ``int` `k, ``int` `[,]dp) ` `{ ` ` `  `    ``// If we get K elements ` `    ``if` `(cnt == k) ` `        ``return` `0; ` ` `  `    ``// If we have reached the end ` `    ``// and K elements are not there ` `    ``if` `(ind == n) ` `        ``return` `(``int``) -1e9; ` ` `  `    ``// If the state has been visited ` `    ``if` `(dp[ind,cnt] != -1) ` `        ``return` `dp[ind,cnt]; ` `    ``int` `ans = 0; ` ` `  `    ``// Iterate for every element as the ` `    ``// next possible element ` `    ``// and take the element which gives ` `    ``// the maximum answer ` `    ``for` `(``int` `i = ind; i < n; i++)  ` `    ``{ ` `        ``// If this element is the first element ` `        ``// in the individual pair in the subsequence ` `        ``// then simply recurrence with the last ` `        ``// element as i-th index ` `        ``if` `(cnt % 2 == 0) ` `            ``ans = Math.Max(ans,recur(i + 1, cnt + 1, i, a, n, k, dp)); ` ` `  `        ``// If this element is the second element in ` `        ``// the individual pair, the find gcd with ` `        ``// the previous element and add to the answer ` `        ``// and recur for the next element ` `        ``else` `            ``ans = Math.Max(ans, __gcd(a[last], a[i]) +  ` `                ``recur(i + 1, cnt + 1, 0, a, n, k, dp)); ` `    ``} ` ` `  `    ``return` `dp[ind,cnt] = ans; ` `} ` ` `  `static` `int` `__gcd(``int` `a, ``int` `b)  ` `{  ` `    ``if` `(b == 0)  ` `        ``return` `a;  ` `    ``return` `__gcd(b, a % b);  ` `     `  `} ` ` `  `// Driver Code ` `public` `static` `void` `Main(String[] args) ` `{ ` `    ``int` `[]a = { 4, 5, 3, 7, 8, 10, 9, 8 }; ` `    ``int` `n = a.Length; ` `    ``int` `k = 4; ` `    ``int` `[,]dp = ``new` `int``[n,MAX]; ` `    ``for``(``int` `i = 0; i < n; i++) ` `    ``{ ` `        ``for``(``int` `j = 0; j < MAX; j++) ` `        ``{ ` `            ``dp[i,j] = -1; ` `        ``} ` `    ``} ` `    ``Console.WriteLine(recur(0, 0, 0, a, n, k, dp)); ` `} ` `} ` ` `  `// This code is contributed by Princi Singh `

Output:

```9
```

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

My Personal Notes arrow_drop_up 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.