Related Articles

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

• Last Updated : 11 May, 2021

Given an array arr[], the task is to find the sum of a subsequence that forms a perfect square. If there are multiple subsequences having a 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`

## Javascript

 ``
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.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

My Personal Notes arrow_drop_up