📌  相关文章
📜  通过选择K个数组元素,然后将它们减1,可以最大程度地增加总和

📅  最后修改于: 2021-05-17 19:03:43             🧑  作者: Mango

给定一个数组arr [] ,该数组由N个正整数和一个整数K组成。在一个操作中,选择一个数组元素,将其添加到总和中,然后将其减1 。任务是打印可以通过执行K次操作获得的最大和。

例子:

天真的方法:最简单的方法是每次使用“最大堆”选择最大元素。将最大元素添加到总和中,然后从“最大堆”中将其删除,然后添加(maximum element – 1) 。执行此操作K并打印总和。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to find maximum possible
// after adding elements K times and
// decrementing each added value by 1
long maxSum(vector arr, int k)
{
     
    // Stores the maximum sum
    long max_sum = 0;
 
    // Create max_heap to get
    // the maximum element
    priority_queue max_heap;
 
    // Update the max_heap
    for(int t : arr)
        max_heap.push(t);
 
    // Calculate the max_sum
    while (k-- > 0)
    {
        int tmp = max_heap.top();
        max_heap.pop();
        max_sum += tmp;
        max_heap.push(tmp - 1);
    }
 
    // Return the maximum sum
    return max_sum;
}
 
// Driver code
int main()
{
     
    // Given an array arr[]
    vector arr = { 2, 5 };
     
    // Given K
    int K = 4;
     
    // Function Call
    cout << maxSum(arr, K);
}
 
// This code is contributed by mohit kumar 29


Java
// Java program for the above approach
import java.util.*;
 
class GFG {
 
    // Function to find maximum possible
    // after adding elements K times and
    // decrementing each added value by 1
    public static long maxSum(int[] arr,
                              int k)
    {
        // Stores the maximum sum
        long max_sum = 0;
 
        // Create max_heap to get
        // the maximum element
        PriorityQueue max_heap
            = new PriorityQueue<>(
                Collections.reverseOrder());
 
        // Update the max_heap
        for (int t : arr)
            max_heap.add(t);
 
        // Calculate the max_sum
        while (k-- > 0) {
            int tmp = max_heap.poll();
            max_sum += tmp;
            max_heap.add(tmp - 1);
        }
 
        // Return the maximum sum
        return max_sum;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        // Given an array arr[]
        int[] arr = { 2, 5 };
 
        // Given K
        int K = 4;
 
        // Function Call
        System.out.println(maxSum(arr, K));
    }
}


Python3
# Python3 program for the above approach
 
# Function to find maximum possible
# after adding elements K times and
# decrementing each added value by 1
from heapq import heappop, heappush, heapify
 
def maxSum(arr, k):
     
    # Stores the maximum sum
    max_sum = 0
 
    # Create max_heap to get
    # the maximum element
    max_heap = []
    heapify(max_heap)
 
    # Update the max_heap
    for i in range(len(arr) - 1, 0, -1):
        heappush(max_heap, arr[i])
         
    # Calculate the max_sum
    while (k > 0):
        tmp = heappop(max_heap)
        max_sum += tmp
        #max_heap.put(tmp - 1);
        heappush(max_heap, tmp - 1)
        k -= 1
 
    # Return the maximum sum
    return max_sum
 
# Driver Code
if __name__ == '__main__':
     
    # Given an array arr
    arr = [ 2, 5 ]
 
    # Given K
    K = 4
 
    # Function Call
    print(maxSum(arr, K))
 
# This code is contributed by gauravrajput1


C#
// C# program for the
// above approach
using System;
using System.Collections.Generic;
 
class GFG{
 
// Function to find maximum possible
// after adding elements K times and
// decrementing each added value by 1
public static long maxSum(int[] arr, int k)
{
     
    // Stores the maximum sum
    long max_sum = 0;
 
    // Create max_heap to get
    // the maximum element
    List max_heap = new List();
 
    // Update the max_heap
    foreach(int t in arr) max_heap.Add(t);
    max_heap.Sort();
    max_heap.Reverse();
     
    // Calculate the max_sum
    while (k-- > 1)
    {
        int tmp = max_heap[0];
        max_heap.Remove(0);
        max_sum += tmp;
        max_heap.Add(tmp - 1);
        max_heap.Sort();
        max_heap.Reverse();
    }
     
    // Return the maximum sum
    return max_sum - 1;
}
 
// Driver Code
public static void Main(String[] args)
{
     
    // Given an array []arr
    int[] arr = { 2, 5 };
     
    // Given K
    int K = 4;
 
    // Function Call
    Console.WriteLine(maxSum(arr, K));
}
}
 
// This code is contributed by gauravrajput1


C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to find maximum possible
// after adding elements K times and
// decrementing each added value by 1
long maxSum(int arr[], int k, int n)
{
     
    // Stores the maximum sum
    long max_sum = 0;
 
    // Stores freqency of element
    int freq[100000 + 1] = {0};
 
    // Update freqency of array element
    for(int i = 0; i < n; i++)
        freq[arr[i]]++;
 
    // Traverse from right to left in
    // freq[] to find maximum sum
    for(int i = 100000; i > 0; i--)
    {
        if (k >= freq[i])
        {
             
            // Update max_sum
            max_sum += i * freq[i];
 
            // Decrement k
            k -= freq[i];
            freq[i - 1] += freq[i];
        }
 
        // Update max_sum and break
        else
        {
            max_sum += i * k;
            break;
        }
    }
 
    // Return the maximum sum
    return max_sum;
}
 
// Driver Code
int main()
{
     
    // Given array arr[]
    int arr[] = { 2, 5 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    // Given K
    int K = 4;
 
    // Function Call
    cout << (maxSum(arr, K, n));
    return 0;
}
 
// This code is contributed by chitranayal


Java
// Java program for the above approach
import java.util.*;
 
class GFG {
 
    // Function to find maximum possible
    // after adding elements K times and
    // decrementing each added value by 1
    public static long maxSum(int[] arr,
                              int k)
    {
        // Stores the maximum sum
        long max_sum = 0;
 
        // Stores freqency of element
        int[] freq = new int[100000 + 1];
 
        // Update freqency of array element
        for (int t : arr)
            freq[t]++;
 
        // Traverse from right to left in
        // freq[] to find maximum sum
        for (int i = 100000; i > 0; i--) {
 
            if (k >= freq[i]) {
 
                // Update max_sum
                max_sum += i * freq[i];
 
                // Decrement k
                k -= freq[i];
                freq[i - 1] += freq[i];
            }
 
            // Update max_sum and break
            else {
                max_sum += i * k;
                break;
            }
        }
 
        // Return the maximum sum
        return max_sum;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        // Given array arr[]
        int[] arr = { 2, 5 };
 
        // Given K
        int K = 4;
 
        // Function Call
        System.out.println(maxSum(arr, K));
    }
}


Python3
# Python program for the above approach
 
# Function to find maximum possible
# after adding elements K times and
# decrementing each added value by 1
def maxSum(arr, k):
   
    # Stores the maximum sum
    max_sum = 0;
 
    # Stores freqency of element
    freq = [0]*(100000 + 1);
 
    # Update freqency of array element
    for i in range(len(arr)):
        freq[arr[i]] += 1;
 
    # Traverse from right to left in
    # freq to find maximum sum
    for i in range(100000, 1, -1):
 
        if (k >= freq[i]):
 
            # Update max_sum
            max_sum += i * freq[i];
 
            # Decrement k
            k -= freq[i];
            freq[i - 1] += freq[i];
 
        # Update max_sum and break
        else:
            max_sum += i * k;
            break;
 
    # Return the maximum sum
    return max_sum;
 
# Driver Code
if __name__ == '__main__':
  
    # Given array arr
    arr = [2, 5];
 
    # Given K
    K = 4;
 
    # Function Call
    print(maxSum(arr, K));
 
    # This code contributed by gauravrajput1


C#
// C# program for the
// above approach
using System;
class GFG{
 
// Function to find maximum possible
// after adding elements K times and
// decrementing each added value by 1
public static long maxSum(int[] arr,
                          int k)
{
  // Stores the maximum
  // sum
  long max_sum = 0;
 
  // Stores freqency of
  // element
  int[] freq =
        new int[100000 + 1];
 
  // Update freqency of
  // array element
  foreach (int t in arr)
  {
    freq[t]++;
  }
 
  // Traverse from right to
  // left in []freq to find
  // maximum sum
  for (int i = 100000; i > 0; i--)
  {
    if (k >= freq[i])
    {
      // Update max_sum
      max_sum += i * freq[i];
 
      // Decrement k
      k -= freq[i];
      freq[i - 1] += freq[i];
    }
 
    // Update max_sum and
    // break
    else
    {
      max_sum += i * k;
      break;
    }
  }
 
  // Return the maximum
  // sum
  return max_sum;
}
 
// Driver Code
public static void Main(String[] args)
{
  // Given array []arr
  int[] arr = {2, 5};
 
  // Given K
  int K = 4;
 
  // Function Call
  Console.WriteLine(
  maxSum(arr, K));
}
}
 
// This code is contributed by gauravrajput1


输出:
14

时间复杂度: O(K * log(N)),其中N是给定数组的长度,K是给定的操作数。
辅助空间: O(N)

高效方法:想法是通过存储给定数组的每个元素的频率来使用哈希概念。请按照以下步骤解决问题:

  • 创建大小为M + 1的freq [] ,其中M是给定数组中存在的最大元素,并且变量max_sum分别存储arr []的每个元素的频率和最大可能和。
  • 从右到左遍历数组freq [] ,即从i = M0
  • 通过频率增量max_sum [I] * 1,会降低K频率[i]和增量频率[I – 1]频率[I],如果K≥频率[i]中
  • 否则,将max_sumi * K并中断循环,因为K变为0
  • 返回max_sum作为最大可能的总和。

下面是上述方法的实现:

C++

// C++ program for the above approach
#include 
using namespace std;
 
// Function to find maximum possible
// after adding elements K times and
// decrementing each added value by 1
long maxSum(int arr[], int k, int n)
{
     
    // Stores the maximum sum
    long max_sum = 0;
 
    // Stores freqency of element
    int freq[100000 + 1] = {0};
 
    // Update freqency of array element
    for(int i = 0; i < n; i++)
        freq[arr[i]]++;
 
    // Traverse from right to left in
    // freq[] to find maximum sum
    for(int i = 100000; i > 0; i--)
    {
        if (k >= freq[i])
        {
             
            // Update max_sum
            max_sum += i * freq[i];
 
            // Decrement k
            k -= freq[i];
            freq[i - 1] += freq[i];
        }
 
        // Update max_sum and break
        else
        {
            max_sum += i * k;
            break;
        }
    }
 
    // Return the maximum sum
    return max_sum;
}
 
// Driver Code
int main()
{
     
    // Given array arr[]
    int arr[] = { 2, 5 };
    int n = sizeof(arr) / sizeof(arr[0]);
 
    // Given K
    int K = 4;
 
    // Function Call
    cout << (maxSum(arr, K, n));
    return 0;
}
 
// This code is contributed by chitranayal

Java

// Java program for the above approach
import java.util.*;
 
class GFG {
 
    // Function to find maximum possible
    // after adding elements K times and
    // decrementing each added value by 1
    public static long maxSum(int[] arr,
                              int k)
    {
        // Stores the maximum sum
        long max_sum = 0;
 
        // Stores freqency of element
        int[] freq = new int[100000 + 1];
 
        // Update freqency of array element
        for (int t : arr)
            freq[t]++;
 
        // Traverse from right to left in
        // freq[] to find maximum sum
        for (int i = 100000; i > 0; i--) {
 
            if (k >= freq[i]) {
 
                // Update max_sum
                max_sum += i * freq[i];
 
                // Decrement k
                k -= freq[i];
                freq[i - 1] += freq[i];
            }
 
            // Update max_sum and break
            else {
                max_sum += i * k;
                break;
            }
        }
 
        // Return the maximum sum
        return max_sum;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        // Given array arr[]
        int[] arr = { 2, 5 };
 
        // Given K
        int K = 4;
 
        // Function Call
        System.out.println(maxSum(arr, K));
    }
}

Python3

# Python program for the above approach
 
# Function to find maximum possible
# after adding elements K times and
# decrementing each added value by 1
def maxSum(arr, k):
   
    # Stores the maximum sum
    max_sum = 0;
 
    # Stores freqency of element
    freq = [0]*(100000 + 1);
 
    # Update freqency of array element
    for i in range(len(arr)):
        freq[arr[i]] += 1;
 
    # Traverse from right to left in
    # freq to find maximum sum
    for i in range(100000, 1, -1):
 
        if (k >= freq[i]):
 
            # Update max_sum
            max_sum += i * freq[i];
 
            # Decrement k
            k -= freq[i];
            freq[i - 1] += freq[i];
 
        # Update max_sum and break
        else:
            max_sum += i * k;
            break;
 
    # Return the maximum sum
    return max_sum;
 
# Driver Code
if __name__ == '__main__':
  
    # Given array arr
    arr = [2, 5];
 
    # Given K
    K = 4;
 
    # Function Call
    print(maxSum(arr, K));
 
    # This code contributed by gauravrajput1

C#

// C# program for the
// above approach
using System;
class GFG{
 
// Function to find maximum possible
// after adding elements K times and
// decrementing each added value by 1
public static long maxSum(int[] arr,
                          int k)
{
  // Stores the maximum
  // sum
  long max_sum = 0;
 
  // Stores freqency of
  // element
  int[] freq =
        new int[100000 + 1];
 
  // Update freqency of
  // array element
  foreach (int t in arr)
  {
    freq[t]++;
  }
 
  // Traverse from right to
  // left in []freq to find
  // maximum sum
  for (int i = 100000; i > 0; i--)
  {
    if (k >= freq[i])
    {
      // Update max_sum
      max_sum += i * freq[i];
 
      // Decrement k
      k -= freq[i];
      freq[i - 1] += freq[i];
    }
 
    // Update max_sum and
    // break
    else
    {
      max_sum += i * k;
      break;
    }
  }
 
  // Return the maximum
  // sum
  return max_sum;
}
 
// Driver Code
public static void Main(String[] args)
{
  // Given array []arr
  int[] arr = {2, 5};
 
  // Given K
  int K = 4;
 
  // Function Call
  Console.WriteLine(
  maxSum(arr, K));
}
}
 
// This code is contributed by gauravrajput1
输出:
14

时间复杂度: O(N),其中N是给定数组的长度。
辅助空间: O(N)