Related Articles
Maximum subsequence sum from a given array which is a perfect square
• Last Updated : 05 Aug, 2020

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.
Follow the steps given below:

• 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 mathematical concepts for competitive programming with the Essential Maths for CP Course at a student-friendly price. To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

My Personal Notes arrow_drop_up