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

• Difficulty Level : Medium
• Last Updated : 22 Jun, 2022

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 maximum.
Note: K is even.
Examples:

Input: a[] = {4, 5, 3, 7, 8, 10, 9, 8}, k = 4
Output:
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.

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`

## Javascript

 ``

Output:

`9`

Time Complexity: O(N*k), as we are using a loop to traverse N times and in each traversal we are recursively calling the function which will cost O(k) time. Where N is the number of elements in the array.

Auxiliary Space: O(N*100), as we are using extra space for the dp matrix. Where N is the number of elements in the array.

My Personal Notes arrow_drop_up