# Maximum subsequence sum from a given array which is a perfect square

Given an array arr[], the task is to fnd the sum of a subsequence which forms a perfect square. If there are multiple subsequences having sum equal to a perfect square, print the maximum sum.
Explanation:

Input: arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}
Output: 36
Explanation:
Maximum possible sum which is a perfect square that can be obtained from the array is 36 obtained from the subsequence {1, 5, 6, 7, 8, 9}.
Input: arr[] = {9, 10}
Output:

Naive Approach: Generate all the possible subsequences of a given array and for each subsequence, check if its sum is a Perfect Square. If such a sum is found, update the maximum sum. Finally, print the maximum sum obtained.
Time Complexity: O(N * 2N
Auxiliary Space: O(N)

Efficient Approach:
The above approach can be optimized by using Dynamic Programming approach.

• Calculate the sum of the array.
• Iterate k in the range [√sum, 0] and check if any subsequence exists with that sum k2. For every k, follow the steps below:
• Initialize boolean matrix subset[][] of dimensions N * sum, where sum denotes the current value of k2.
• subset[i][j] denotes whether a subsequence of size i with sum j exists or not.
• Initialize first column and first row as true and false respectively of subset[][].
• Run two nested loops, outer from i in the range [1, N] and inner j in the range [1, sum]to fill the subset[][] matrix in bottom up manner based on the following conditions:
• if (j < arr[i – 1]), then subset[i][j] = subset[i – 1][j]
• if (j >= arr[i – 1]), then subset[i][j] = subset[i – 1][j] || subset[i – 1][j – arr[i – 1]]
• Finally, return the subset[n][sum].
• The first k for which subset[n][k] is true, gives the required maximum possible subsequence sum k2.

Below is the implementation of the above approach:

## C++

 `// C++ Program to implement ` `// the above approach ` `#include ` `using` `namespace` `std; ` `bool` `isSubsetSum(``int` `arr[], ``int` `n, ``int` `sum) ` `{ ` `    ``bool` `subset[n + 1][sum + 1]; ` ` `  `    ``// If sum is 0, then answer is true ` `    ``for` `(``int` `i = 0; i <= n; i++) ` `        ``subset[i] = ``true``; ` ` `  `    ``// If sum is not 0 and arr[] is empty, ` `    ``// then answer is false ` `    ``for` `(``int` `i = 1; i <= sum; i++) ` `        ``subset[i] = ``false``; ` ` `  `    ``// Fill the subset table in bottom up manner ` `    ``for` `(``int` `i = 1; i <= n; i++) { ` `        ``for` `(``int` `j = 1; j <= sum; j++) { ` ` `  `            ``if` `(j < arr[i - 1]) ` `                ``subset[i][j] = subset[i - 1][j]; ` ` `  `            ``if` `(j >= arr[i - 1]) ` `                ``subset[i][j] ` `                    ``= subset[i - 1][j] ` `                      ``|| subset[i - 1][j - arr[i - 1]]; ` `        ``} ` `    ``} ` ` `  `    ``return` `subset[n][sum]; ` `} ` `// Function to find the sum ` `int` `findSum(``int``* arr, ``int` `n) ` `{ ` `    ``int` `sum = 0; ` `    ``// Find sum of all values ` `    ``for` `(``int` `i = 0; i < n; i++) { ` `        ``sum += arr[i]; ` `    ``} ` ` `  `    ``int` `val = ``sqrt``(sum); ` ` `  `    ``for` `(``int` `i = val; i >= 0; i--) { ` `        ``if` `(isSubsetSum(arr, n, i * i)) { ` `            ``// return the value; ` `            ``return` `i * i; ` `        ``} ` `    ``} ` ` `  `    ``return` `0; ` `} ` ` `  `// Driver Code ` `int` `main() ` `{ ` `    ``int` `arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ` `    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr); ` `    ``cout << findSum(arr, n) << endl; ` `    ``return` `0; ` `} `

## Java

 `// Java program to implement  ` `// the above approach  ` `import` `java.util.*; ` ` `  `class` `GFG{ ` ` `  `static` `boolean` `isSubsetSum(``int` `arr[],  ` `                           ``int` `n, ``int` `sum) ` `{ ` `    ``boolean``[][] subset = ``new` `boolean``[n + ``1``][sum + ``1``]; ` ` `  `    ``// If sum is 0, then answer is true ` `    ``for``(``int` `i = ``0``; i <= n; i++) ` `        ``subset[i][``0``] = ``true``; ` ` `  `    ``// If sum is not 0 and arr[] is empty, ` `    ``// then answer is false ` `    ``for``(``int` `i = ``1``; i <= sum; i++) ` `        ``subset[``0``][i] = ``false``; ` ` `  `    ``// Fill the subset table in bottom up manner ` `    ``for``(``int` `i = ``1``; i <= n; i++) ` `    ``{ ` `        ``for``(``int` `j = ``1``; j <= sum; j++) ` `        ``{ ` `            ``if` `(j < arr[i - ``1``]) ` `                ``subset[i][j] = subset[i - ``1``][j]; ` ` `  `            ``if` `(j >= arr[i - ``1``]) ` `                ``subset[i][j] = subset[i - ``1``][j] || ` `                ``subset[i - ``1``][j - arr[i - ``1``]]; ` `        ``} ` `    ``} ` `    ``return` `subset[n][sum]; ` `} ` ` `  `// Function to find the sum ` `static` `int` `findSum(``int``[] arr, ``int` `n) ` `{ ` `    ``int` `sum = ``0``; ` `     `  `    ``// Find sum of all values ` `    ``for``(``int` `i = ``0``; i < n; i++) ` `    ``{ ` `        ``sum += arr[i]; ` `    ``} ` ` `  `    ``int` `val = (``int``)Math.sqrt(sum); ` ` `  `    ``for``(``int` `i = val; i >= ``0``; i--) ` `    ``{ ` `        ``if` `(isSubsetSum(arr, n, i * i)) ` `        ``{ ` `             `  `            ``// return the value; ` `            ``return` `i * i; ` `        ``} ` `    ``} ` `    ``return` `0``; ` `} ` ` `  `// Driver code ` `public` `static` `void` `main(String[] args) ` `{ ` `    ``int` `arr[] = { ``1``, ``2``, ``3``, ``4``, ``5``, ``6``, ``7``, ``8``, ``9` `}; ` `    ``int` `n = arr.length; ` `     `  `    ``System.out.println(findSum(arr, n)); ` `} ` `} ` ` `  `// This code is contributed by offbeat `

## Python3

 `# Python3 program to implement ` `# the above approach ` `import` `math ` ` `  `def` `isSubsetSum(arr, n, ``sum``): ` `     `  `    ``subset ``=` `[ [ ``True` `for` `x ``in` `range``(``sum` `+` `1``) ]  ` `                      ``for` `y ``in` `range``(n ``+` `1``) ] ` ` `  `    ``# If sum is 0, then answer is true ` `    ``for` `i ``in` `range``(n ``+` `1``): ` `        ``subset[i][``0``] ``=` `True` ` `  `    ``# If sum is not 0 and arr[] is empty, ` `    ``# then answer is false ` `    ``for` `i ``in` `range``(``1``, ``sum` `+` `1``): ` `        ``subset[``0``][i] ``=` `False` ` `  `    ``# Fill the subset table in bottom up manner ` `    ``for` `i ``in` `range``(``1``, n ``+` `1``): ` `        ``for` `j ``in` `range``(``1``, ``sum` `+` `1``): ` ` `  `            ``if` `(j < arr[i ``-` `1``]): ` `                ``subset[i][j] ``=` `subset[i ``-` `1``][j] ` ` `  `            ``if` `(j >``=` `arr[i ``-` `1``]): ` `                ``subset[i][j] ``=` `(subset[i ``-` `1``][j] ``or` `                                ``subset[i ``-` `1``][j ``-`  `                                   ``arr[i ``-` `1``]]) ` `                                    `  `    ``return` `subset[n][``sum``] ` ` `  `# Function to find the sum ` `def` `findSum(arr, n): ` `     `  `    ``sum` `=` `0` `     `  `    ``# Find sum of all values ` `    ``for` `i ``in` `range``(n): ` `        ``sum` `+``=` `arr[i] ` ` `  `    ``val ``=` `int``(math.sqrt(``sum``)) ` ` `  `    ``for` `i ``in` `range``(val, ``-``1``, ``-``1``): ` `        ``if` `(isSubsetSum(arr, n, i ``*` `i)): ` `             `  `            ``# Return the value; ` `            ``return` `i ``*` `i ` `             `  `    ``return` `0` ` `  `# Driver Code ` `if` `__name__ ``=``=` `"__main__"``: ` ` `  `    ``arr ``=` `[ ``1``, ``2``, ``3``, ``4``, ``5``, ``6``, ``7``, ``8``, ``9``] ` `    ``n ``=` `len``(arr) ` `     `  `    ``print``(findSum(arr, n)) ` ` `  `# This code is contributed by chitranayal `

## C#

 `// C# program to implement  ` `// the above approach  ` `using` `System; ` ` `  `class` `GFG{ ` ` `  `static` `bool` `isSubsetSum(``int` `[]arr,  ` `                        ``int` `n, ``int` `sum) ` `{ ` `    ``bool``[,] subset = ``new` `bool``[n + 1, sum + 1]; ` ` `  `    ``// If sum is 0, then answer is true ` `    ``for``(``int` `i = 0; i <= n; i++) ` `        ``subset[i, 0] = ``true``; ` ` `  `    ``// If sum is not 0 and []arr is empty, ` `    ``// then answer is false ` `    ``for``(``int` `i = 1; i <= sum; i++) ` `        ``subset[0, i] = ``false``; ` ` `  `    ``// Fill the subset table in bottom up manner ` `    ``for``(``int` `i = 1; i <= n; i++) ` `    ``{ ` `        ``for``(``int` `j = 1; j <= sum; j++) ` `        ``{ ` `            ``if` `(j < arr[i - 1]) ` `                ``subset[i, j] = subset[i - 1, j]; ` ` `  `            ``if` `(j >= arr[i - 1]) ` `                ``subset[i, j] = subset[i - 1, j] || ` `                ``subset[i - 1, j - arr[i - 1]]; ` `        ``} ` `    ``} ` `    ``return` `subset[n, sum]; ` `} ` ` `  `// Function to find the sum ` `static` `int` `findSum(``int``[] arr, ``int` `n) ` `{ ` `    ``int` `sum = 0; ` `     `  `    ``// Find sum of all values ` `    ``for``(``int` `i = 0; i < n; i++) ` `    ``{ ` `        ``sum += arr[i]; ` `    ``} ` ` `  `    ``int` `val = (``int``)Math.Sqrt(sum); ` ` `  `    ``for``(``int` `i = val; i >= 0; i--) ` `    ``{ ` `        ``if` `(isSubsetSum(arr, n, i * i)) ` `        ``{ ` `             `  `            ``// return the value; ` `            ``return` `i * i; ` `        ``} ` `    ``} ` `    ``return` `0; ` `} ` ` `  `// Driver code ` `public` `static` `void` `Main(String[] args) ` `{ ` `    ``int` `[]arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; ` `    ``int` `n = arr.Length; ` `     `  `    ``Console.WriteLine(findSum(arr, n)); ` `} ` `} ` ` `  `// This code is contributed by Rohit_ranjan `

Output:

```36
```

Time Complexity: O(N * SUM)
Auxiliary Space: O(N * SUM)

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.