Maximum subsequence sum from a given array which is a perfect square
Last Updated :
26 Oct, 2023
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: 9
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 <bits/stdc++.h>
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][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
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[0]);
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
<script>
// JavaScript program to implement
// the above approach
function isSubsetSum(arr, n, sum)
{
let subset = new Array(n + 1);
for (var i = 0; i < subset.length; i++) {
subset[i] = new Array(2);
}
// If sum is 0, then answer is true
for(let i = 0; i <= n; i++)
subset[i][0] = true;
// If sum is not 0 and arr[] is empty,
// then answer is false
for(let i = 1; i <= sum; i++)
subset[0][i] = false;
// Fill the subset table in bottom up manner
for(let i = 1; i <= n; i++)
{
for(let 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
function findSum(arr, n)
{
let sum = 0;
// Find sum of all values
for(let i = 0; i < n; i++)
{
sum += arr[i];
}
let val = Math.floor(Math.sqrt(sum));
for(let i = val; i >= 0; i--)
{
if (isSubsetSum(arr, n, i * i))
{
// return the value;
return i * i;
}
}
return 0;
}
// Driver Code
let arr = [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ];
let n = arr.length;
document.write(findSum(arr, n));
</script>
Time Complexity: O(N * SUM)
Auxiliary Space: O(N * SUM)
Efficient approach : Space optimization
In previous approach the current value subset[i][j] is only depend upon the current and previous row values of DP. So to optimize the space complexity we use a single 1D array to store the computations.
Implementation steps:
- Create a 1D array subset of size sum+1 and initialize it with false.
- Set a base case and initialize subset[0] = True.
- Now iterate over subproblems by the help of nested loop and get the current value from previous computations.
- At last return the final answer stored in subset[sum].
Implementation:
C++
// C++ Program to implement
// the above approach
#include <bits/stdc++.h>
using namespace std;
bool isSubsetSum(int arr[], int n, int sum)
{
bool subset[sum + 1];
memset(subset, false, sizeof(subset));
// If sum is 0, then answer is true
subset[0] = true;
// iterative over subproblems to get the
// current value from previous computations
for (int i = 0; i < n; i++) {
for (int j = sum; j >= arr[i]; j--) {
subset[j] = subset[j] || subset[j - arr[i]];
}
}
// return final answer
return subset[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[0]);
// function call
cout << findSum(arr, n) << endl;
return 0;
}
// this code is contributed by bhardwajji
Java
// Java program to implement
// the above approach
import java.io.*;
import java.util.*;
class GFG {
static boolean isSubsetSum(int[] arr, int n, int sum)
{
boolean[] subset = new boolean[sum + 1];
Arrays.fill(subset, false);
// If sum is 0, then answer is true
subset[0] = true;
// iterative over subproblems to get the
// current value from previous computations
for (int i = 0; i < n; i++) {
for (int j = sum; j >= arr[i]; j--) {
subset[j] = subset[j] || subset[j - arr[i]];
}
}
// return final answer
return subset[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;
// function call
System.out.println(findSum(arr, n));
}
}
Python3
import math
# Function to check if a subset with
# given sum exists in the array
def isSubsetSum(arr, n, target):
# Initialize a boolean array
# subset of size target+1 and
# fill it with False
subset = [False] * (target + 1)
# Set subset[0] to True as a subset
# with sum 0 always exists
subset[0] = True
# Iterate through all elements
# in the array
for i in range(n):
# Iterate backwards through the
# subset array starting from target
# and going down to arr[i]
# This is done to avoid recomputing
# subsets that have already been checked
for j in range(target, arr[i] - 1, -1):
# If subset[j-arr[i]] is True, then
# a subset with sum j-arr[i] exists
# Therefore, a subset with sum j can
# be formed by adding arr[i] to this subset
subset[j] = subset[j] or subset[j - arr[i]]
# Return True if a subset with the
# target sum exists, else False
return subset[target]
# Function to find the largest perfect square
# less than or equal to the sum of all elements
# in the array
def findSum(arr, n):
# Find the sum of all elements
# in the array
total_sum = sum(arr)
# Find the square root of the sum of all
# elements and cast it to an integer
val = int(math.sqrt(total_sum))
# Iterate backwards from the square
# root of the sum of all elements
for i in range(val, -1, -1):
# If a subset with sum i*i exists,
# return i*i
if isSubsetSum(arr, n, i * i):
return i * i
# If no perfect square is found,
# return 0
return 0
# Driver Code
if __name__ == "__main__":
# Initialize an array of integers
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
# Find the length of the array
n = len(arr)
# Call the findSum function and
# print the result
print(findSum(arr, n))
C#
using System;
public class GFG {
static bool isSubsetSum(int[] arr, int n, int sum)
{
bool[] subset = new bool[sum + 1];
Array.Fill(subset, false);
// If sum is 0, then answer is true
subset[0] = true;
// iterative over subproblems to get the
// current value from previous computations
for (int i = 0; i < n; i++) {
for (int j = sum; j >= arr[i]; j--) {
subset[j] = subset[j] || subset[j - arr[i]];
}
}
// return final answer
return subset[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;
}
public static void Main()
{
int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int n = arr.Length;
// function call
Console.WriteLine(findSum(arr, n));
}
}
JavaScript
function isSubsetSum(arr, n, sum) {
const subset = new Array(sum + 1).fill(false);
// If sum is 0, then the answer is true
subset[0] = true;
// Iterate over subproblems to get the current value from previous computations
for (let i = 0; i < n; i++) {
for (let j = sum; j >= arr[i]; j--) {
subset[j] = subset[j] || subset[j - arr[i]];
}
}
// Return the final answer
return subset[sum];
}
function findSum(arr, n) {
let sum = 0;
// Find the sum of all values
for (let i = 0; i < n; i++) {
sum += arr[i];
}
const val = Math.floor(Math.sqrt(sum));
for (let i = val; i >= 0; i--) {
if (isSubsetSum(arr, n, i * i)) {
// Return the value
return i * i;
}
}
return 0;
}
// Driver Code
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const n = arr.length;
// Function call
console.log(findSum(arr, n));
Time Complexity: O(N * SUM)
Auxiliary Space: O(SUM)
Similar Reads
Find the Maximum Alternate Subsequence Sum from a given array
Given an array arr[] of size n having both positive and negative integer excluding zero. Find the maximum sum of maximum size alternate subsequence of a given sequence that is, in a subsequence sign of each adjacent element is opposite for example if the first one is positive then the second one has
5 min read
Count of pairs in an array whose sum is a perfect square
Given an array arr of distinct elements, the task is to find the total number of two element pairs from the array whose sum is a perfect square. Examples: Input: arr[] = {2, 3, 6, 9, 10, 20} Output: 2 Only possible pairs are (3, 6) and (6, 10) Input: arr[] = {9, 2, 5, 1} Output: 0 Naive Approach: Us
12 min read
Find a subsequence which upon reversing gives the maximum sum subarray
Given an array arr of integers of size N, the task is to find a subsequence in which upon reversing the order, the maximum sum subarray can be obtained. Examples: Input: arr[] = {-2, -3, 4, -1, -2, 1, 5, -3}Output: [-2 -3 1 5]Explanation : After selecting subsequence -2 -3 1 5 and reverse it element
6 min read
Maximize the Sum of a Subsequence from an Array based on given conditions
Given an array a[] consisting of N integers, the task is to perform the following operations: Select a subsequence and for every pth element of the subsequence, calculate the product p * a[i].Calculate the sum of the calculated values of p * a[i].The subsequence should be selected such that it maxim
7 min read
Longest alternating subsequence with maximum sum | Set 2
Given an array arr[] of size N, consisting of positive and negative integers, the task is to find the longest alternating subsequence(i.e. the sign of every element is opposite to that of its previous element) from the given array which has the maximum sum.Examples: Input: arr[] = {-2, 10, 3, -8, -4
7 min read
Maximum sum subsequence of any size which is decreasing-increasing alternatively
Given an array of integers arr[], find the subsequence with maximum sum whose elements are first decreasing, then increasing, or vice versa, The subsequence can start anywhere in the main sequence, not necessarily at the first element of the main sequence. A sequence {x1, x2, .. xn} is an alternatin
15+ min read
Maximum sum increasing subsequence from a prefix and a given element after prefix is must
Given an array of n positive integers, write a program to find the maximum sum of increasing subsequence from prefix till ith index and also including a given kth element which is after i, i.e., k > i. Examples : Input: arr[] = {1, 101, 2, 3, 100, 4, 5} i-th index = 4 (Element at 4th index is 100
14 min read
Number of subsequences of an array with given function value
Given an array A[] of length N and integer F, the task is to find the number of subsequences where the average of the sum of the square of elements (of that particular subsequence) is equal to the value F. Examples: Input: A[] = {1, 2, 1, 2}, F = 2Output: 2Explanation: Two subsets with value F = 2 a
12 min read
Longest alternating subsequence which has maximum sum of elements
Given a list of length N with positive and negative integers. The task is to choose the longest alternating subsequence of the given sequence (i.e. the sign of each next element is the opposite of the sign of the current element). Among all such subsequences, we have to choose one which has the maxi
10 min read
Maximum Subarray Sum possible by replacing an Array element by its Square
Given an array a[] consisting of N integers, the task is to find the maximum subarray sum that can be obtained by replacing a single array element by its square. Examples: Input: a[] = {1, -5, 8, 12, -8} Output: 152 Explanation: Replacing 12 by 144, the subarray {8, 144} generates the maximum possib
12 min read