Suma máxima de subsecuencias de una array dada que es un cuadrado perfecto

Dada una array arr[] , la tarea es encontrar la suma de una subsecuencia que forme un cuadrado perfecto . Si hay múltiples subsecuencias que tienen una suma igual a un cuadrado perfecto, imprime la suma máxima .
Explicación: 
 

Entrada: arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9} 
Salida: 36 
Explicación: 
La suma máxima posible que es un cuadrado perfecto que se puede obtener de la array es 36 obtenida de la subsecuencia {1, 5, 6, 7, 8, 9}.
Entrada: arr[] = {9, 10} 
Salida:
 

Enfoque ingenuo: genere todas las subsecuencias posibles de una array dada y, para cada subsecuencia, verifique si su suma es un cuadrado perfecto . Si se encuentra tal suma, actualice la suma máxima . Finalmente, imprima la suma máxima obtenida. 
Complejidad de Tiempo: O(N * 2 N
Espacio Auxiliar: O(N)
 

Enfoque eficiente: 
el enfoque anterior se puede optimizar utilizando el enfoque de programación dinámica
Siga los pasos que se indican a continuación: 
 

  • Calcular la suma de la array.
  • Iterar k en el rango [√sum, 0] y verificar si existe alguna subsecuencia con esa suma k 2 . Para cada k , siga los pasos a continuación: 
    • Inicializa el subconjunto de array booleana[][] de dimensiones N * sum , donde sum denota el valor actual de k 2 .
    • subconjunto[i][j] indica si existe o no una subsecuencia de tamaño i con suma j .
    • Inicialice la primera columna y la primera fila como verdadero y falso respectivamente de subconjunto[][] .
    • Ejecute dos bucles anidados, el exterior desde i en el rango [1, N] y el interior j en el rango [1, suma] para llenar la array del subconjunto [][] de forma ascendente según las siguientes condiciones: 
      • si (j < arr[i – 1]), entonces subconjunto[i][j] = subconjunto[i – 1][j]
      • si (j >= arr[i – 1]), entonces subconjunto[i][j] = subconjunto[i – 1][j] || subconjunto[i – 1][j – arr[i – 1]]
    • Finalmente, devuelve el subconjunto[n][suma] .
  • El primer k para el cual el subconjunto[n][k] es verdadero, da la máxima suma de subsecuencias posible requerida k 2 .

A continuación se muestra la implementación del enfoque anterior:
 

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>
Producción: 

36

 

Complejidad de Tiempo: O(N * SUM)  
Espacio Auxiliar: O(N * SUM)
 

Publicación traducida automáticamente

Artículo escrito por AmanGupta65 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *