Suma máxima del subconjunto que tiene una diferencia entre su máximo y mínimo en el rango [L, R]

Dada una array arr[] de N enteros positivos y un rango [L, R] , la tarea es encontrar la suma máxima del subconjunto tal que la diferencia entre los elementos máximo y mínimo del subconjunto se encuentre en el rango dado.

Ejemplos:

Entrada: arr[] = {6, 5, 0, 9, 1}, L = 0, R = 3
Salida: 15
Explicación: El subconjunto {6, 9} de la array dada tiene la diferencia entre los elementos máximo y mínimo como 3 que se encuentra en el rango dado [0, 3] y la suma de los elementos como 15 que es el máximo posible.

Entrada: arr[] = {5, 10, 15, 20, 25}, L = 1, R = 2
Salida: 0
Explicación: No existen subconjuntos válidos.

Enfoque: el problema dado se puede resolver con la ayuda de una búsqueda binaria después de ordenar la array dada . A continuación se detallan los pasos a seguir:

  • Ordena la array dada en orden no decreciente.
  • Cree una array de suma de prefijos sum [] usando el algoritmo discutido aquí .
  • Recorra la array usando una variable i para todos los valores de i en el rango [0, N) .
  • Para cada i , encuentre el índice j del entero más grande tal que arr[j] <= arr[i] + R . Esto se puede hacer usando la función upper_bound .
  • Mantenga una variable ans , que almacene la suma máxima del subconjunto. Inicialmente, respuesta = 0 .
  • Si el subarreglo arr[i, j] forma un subconjunto válido, actualice el valor de ans al máximo de ans y la suma del subarreglo arr[i, j] .
  • El valor almacenado en ans es la respuesta requerida.

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

CPP

// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to find Maximum Subset Sum such
// that the difference between maximum and
// minimum elements lies in the range [L, R]
int maxSubsetSum(vector<int> arr, int L, int R)
{
    int N = arr.size();
 
    // Sort the given array arr[] in
    // non-decreasing order
    sort(arr.begin(), arr.end());
 
    // Stores the sum of elements till
    // current index of the array arr[]
    int sum[N + 1] = {};
 
    // Stores the Maximum subset sum
    int ans = 0;
 
    // Create prefix sum array
    for (int i = 1; i <= N; i++) {
        sum[i] = sum[i - 1] + arr[i - 1];
    }
 
    // Iterate over all indices of array
    for (int i = 0; i < N; i++) {
 
        // Maximum possible value of
        // subset considering arr[i]
        // as the minimum element
        int val = arr[i] + R;
 
        // Calculate the position of the
        // largest element <= val
        auto ptr = upper_bound(
            arr.begin(), arr.end(), val);
        ptr--;
        int j = ptr - arr.begin();
 
        // If the difference between the
        // maximum and the minimum lies in
        // the range, update answer
        if ((arr[j] - arr[i] <= R)
            && (arr[j] - arr[i] >= L)) {
            ans = max(ans, sum[j + 1] - sum[i]);
        }
    }
 
    // Return Answer
    return ans;
}
 
// Driver Code
int main()
{
    vector<int> arr{ 6, 5, 0, 9, 1 };
    int L = 0;
    int R = 3;
    cout << maxSubsetSum(arr, L, R);
 
    return 0;
}

Java

// Java program for the above approach
import java.util.*;
 
class GFG{
 
  static int upperBound(int[] a, int low, int high, int element){
    while(low < high){
      int middle = low + (high - low)/2;
      if(a[middle] > element)
        high = middle;
      else
        low = middle + 1;
    }
    return low;
  }
 
  // Function to find Maximum Subset Sum such
  // that the difference between maximum and
  // minimum elements lies in the range [L, R]
  static int maxSubsetSum(int[] arr, int L, int R)
  {
    int N = arr.length;
 
    // Sort the given array arr[] in
    // non-decreasing order
    Arrays.sort(arr);
 
    // Stores the sum of elements till
    // current index of the array arr[]
    int []sum  = new int[N + 1];
 
    // Stores the Maximum subset sum
    int ans = 0;
 
    // Create prefix sum array
    for (int i = 1; i <= N; i++) {
      sum[i] = sum[i - 1] + arr[i - 1];
    }
 
    // Iterate over all indices of array
    for (int i = 0; i < N; i++) {
 
      // Maximum possible value of
      // subset considering arr[i]
      // as the minimum element
      int val = arr[i] + R;
 
      // Calculate the position of the
      // largest element <= val
      int ptr = upperBound(arr, 0, N,val);
      ptr--;
      int j = ptr;
 
      // If the difference between the
      // maximum and the minimum lies in
      // the range, update answer
      if ((arr[j] - arr[i] <= R)
          && (arr[j] - arr[i] >= L)) {
        ans = Math.max(ans, sum[j + 1] - sum[i]);
      }
    }
 
    // Return Answer
    return ans;
  }
 
  // Driver Code
  public static void main(String[] args)
  {
    int[] arr = { 6, 5, 0, 9, 1 };
    int L = 0;
    int R = 3;
    System.out.print(maxSubsetSum(arr, L, R));
 
  }
}
 
// This code is contributed by umadevi9616

Python3

# Python Program to implement
# the above approach
from functools import cmp_to_key
 
def cmp_sort(a, b):
    return a - b
 
def InsertionIndex(nums, target, left):
    low = 0
    high = len(nums)
 
    while (low < high):
        mid = low + ((high - low) // 2)
 
        if (nums[mid] > target or (left and target == nums[mid])):
            high = mid
        else:
            low = mid + 1
 
    return low
 
def upper_bound(nums, target):
    targetRange = [-1, -1]
 
    leftIdx = InsertionIndex(nums, target, True)
 
    if (leftIdx == len(nums) or nums[leftIdx] != target):
        return targetRange
 
    targetRange[0] = leftIdx
    targetRange[1] = InsertionIndex(nums, target, False) - 1
 
    return targetRange
 
def maxSubsetSum(arr, L, R):
    N = len(arr)
 
    # Sort the given array arr[] in
    # non-decreasing order
    arr.sort(key = cmp_to_key(cmp_sort))
 
    # Stores the sum of elements till
    # current index of the array arr[]
    sum = [0 for i in range(N+1)]
 
    # Stores the Maximum subset sum
    ans = 0
 
    # Create prefix sum array
    for i in range(1,N+1):
        sum[i] = sum[i - 1] + arr[i - 1]
    # Iterate over all indices of array
    for i in range(N):
 
        # Maximum possible value of
        # subset considering arr[i]
        # as the minimum element
        val = arr[i] + R
 
        # Calculate the position of the
        # largest element <= val
        ptr = upper_bound(arr, val)
        j = ptr[1]
 
        # If the difference between the
        # maximum and the minimum lies in
        # the range, update answer
        if ((arr[j] - arr[i] <= R) and (arr[j] - arr[i] >= L)):
            ans = max(ans, sum[j + 1] - sum[i])
 
    # Return Answer
    return ans
 
# Driver Code
arr = [6, 5, 0, 9, 1]
L = 0
R = 3
print(maxSubsetSum(arr, L, R))
 
# This code is contributed by shinjanpatra

Javascript

<script>
        // JavaScript Program to implement
        // the above approach
        function InsertionIndex(nums, target, left)
        {
            let low = 0,
                high = nums.length
 
            while (low < high) {
                const mid = low + Math.floor((high - low) / 2)
 
                if (nums[mid] > target || (left && target === nums[mid]))
                    high = mid
                else
                    low = mid + 1
            }
 
            return low
        }
        function upper_bound(nums, target) {
            const targetRange = [-1, -1]
 
            const leftIdx = InsertionIndex(nums, target, true)
 
            if (leftIdx === nums.length || nums[leftIdx] != target)
                return targetRange
 
            targetRange[0] = leftIdx
            targetRange[1] = InsertionIndex(nums, target, false) - 1
 
            return targetRange
 
        }
        function maxSubsetSum(arr, L, R) {
            let N = arr.length;
 
            // Sort the given array arr[] in
            // non-decreasing order
            arr.sort(function (a, b) { return a - b })
 
            // Stores the sum of elements till
            // current index of the array arr[]
            let sum = new Array(N + 1).fill(0);
 
            // Stores the Maximum subset sum
            let ans = 0;
 
            // Create prefix sum array
            for (let i = 1; i <= N; i++) {
                sum[i] = sum[i - 1] + arr[i - 1];
            }
 
            // Iterate over all indices of array
            for (let i = 0; i < N; i++) {
 
                // Maximum possible value of
                // subset considering arr[i]
                // as the minimum element
                let val = arr[i] + R;
 
                // Calculate the position of the
                // largest element <= val
                let ptr = upper_bound(
                    arr, val);
                let j = ptr[1]
                 
                // If the difference between the
                // maximum and the minimum lies in
                // the range, update answer
                if ((arr[j] - arr[i] <= R)
                    && (arr[j] - arr[i] >= L)) {
                    ans = Math.max(ans, sum[j + 1] - sum[i]);
                }
            }
 
            // Return Answer
            return ans;
        }
 
        // Driver Code
        let arr = [6, 5, 0, 9, 1];
        let L = 0;
        let R = 3;
        document.write(maxSubsetSum(arr, L, R));
 
    // This code is contributed by Potta Lokesh
    </script>
Producción: 

15

 

Complejidad de tiempo: O(N*log N)
Espacio auxiliar: O(N) 

Publicación traducida automáticamente

Artículo escrito por Shivam.Pradhan 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 *