📌  相关文章
📜  将数组拆分为K个子集,以最大化其最大值和最小值之和

📅  最后修改于: 2021-05-18 01:20:52             🧑  作者: Mango

给定一个整数K和一个长度为K的倍数的数组A [] ,任务是将给定数组的元素拆分为K个子集,每个子集具有相等数量的元素,以使得最大和最小元素之和为每个子集是最大可能的总和。
例子:

天真的方法:
解决此问题的最简单方法是生成大小为N / KK个子集的所有可能组,并为每个组找到每个子集中的最大值和最小值,然后计算它们的总和。计算完所有组的总和后,请打印获得的最大总和。
时间复杂度: O(2 N )
辅助空间: O(N)
高效方法:
这个想法是使用贪婪技术来优化上述方法。由于需要每个子集中的最大和最小元素的最大和,因此请尝试使最大元素和最小元素最大化。对于每个子集的最大元素,请从给定数组中获取前K个最大元素,并将每个元素插入不同的子集。对于每个子集的最小元素,从已排序的数组开始,从索引0开始,以(N / K)– 1个间隔选择每个下一个元素,因为每个子集的大小为N / K,并且每个子集已经包含一个最大元素。
请按照以下步骤操作:

  • 计算每个组中的元素数,即(N / K)
  • 以降序对A []的所有元素进行排序。
  • 对于最大元素的总和,请添加已排序数组中所有K个最大元素。
  • 对于最小元素的总和,从索引0开始,以(N / K)– 1个间隔选择K个元素,并将它们相加。
  • 最后,计算最大和最小元素的总和。打印它们各自总和的总和作为最终答案。

下面是上述方法的实现:

C++
// C++ Program to implement
// the above approach
#include 
using namespace std;
 
// Function that prints
// the maximum sum possible
void maximumSum(int arr[],
                int n, int k)
{
 
    // Find elements in each group
    int elt = n / k;
 
    int sum = 0;
 
    // Sort all elements in
    // non-descending order
    sort(arr, arr + n);
 
    int count = 0;
    int i = n - 1;
 
    // Add K largest elements
    while (count < k) {
        sum += arr[i];
        i--;
        count++;
    }
 
    count = 0;
    i = 0;
 
    // For sum of minimum
    // elements from each subset
    while (count < k) {
        sum += arr[i];
        i += elt - 1;
        count++;
    }
 
    // Printing the maximum sum
    cout << sum << "\n";
}
 
// Driver Code
int main()
{
    int Arr[] = { 1, 13, 7, 17, 6, 5 };
 
    int K = 2;
 
    int size = sizeof(Arr) / sizeof(Arr[0]);
 
    maximumSum(Arr, size, K);
 
    return 0;
}


Java
// Java program to implement
// the above approach
import java.util.Arrays;
 
class GFG{
     
// Function that prints
// the maximum sum possible
static void maximumSum(int arr[],
                       int n, int k)
{
     
    // Find elements in each group
    int elt = n / k;
 
    int sum = 0;
 
    // Sort all elements in
    // non-descending order
    Arrays.sort(arr);
 
    int count = 0;
    int i = n - 1;
 
    // Add K largest elements
    while (count < k)
    {
        sum += arr[i];
        i--;
        count++;
    }
    count = 0;
    i = 0;
 
    // For sum of minimum
    // elements from each subset
    while (count < k)
    {
        sum += arr[i];
        i += elt - 1;
        count++;
    }
 
    // Printing the maximum sum
    System.out.println(sum);
}
 
// Driver code
public static void main (String[] args)
{
    int Arr[] = { 1, 13, 7, 17, 6, 5 };
 
    int K = 2;
 
    int size = Arr.length;
 
    maximumSum(Arr, size, K);
}
}
 
// This code is contributed by Shubham Prakash


Python3
# Python3 program to implement
# the above approach
 
# Function that prints
# the maximum sum possible
def maximumSum(arr, n, k):
   
    # Find elements in each group
    elt = n // k;
 
    sum = 0;
 
    # Sort all elements in
    # non-descending order
    arr.sort();
 
    count = 0;
    i = n - 1;
 
    # Add K largest elements
    while (count < k):
        sum += arr[i];
        i -= 1;
        count += 1;
 
    count = 0;
    i = 0;
 
    # For sum of minimum
    # elements from each subset
    while (count < k):
        sum += arr[i];
        i += elt - 1;
        count += 1;
 
    # Printing the maximum sum
    print(sum);
 
# Driver code
if __name__ == '__main__':
    Arr = [1, 13, 7, 17, 6, 5];
 
    K = 2;
 
    size = len(Arr);
 
    maximumSum(Arr, size, K);
 
# This code is contributed by sapnasingh4991


C#
// C# program to implement
// the above approach
using System;
 
class GFG{
     
// Function that prints
// the maximum sum possible
static void maximumSum(int []arr,
                       int n, int k)
{
     
    // Find elements in each group
    int elt = n / k;
 
    int sum = 0;
 
    // Sort all elements in
    // non-descending order
    Array.Sort(arr);
 
    int count = 0;
    int i = n - 1;
 
    // Add K largest elements
    while (count < k)
    {
        sum += arr[i];
        i--;
        count++;
    }
    count = 0;
    i = 0;
 
    // For sum of minimum
    // elements from each subset
    while (count < k)
    {
        sum += arr[i];
        i += elt - 1;
        count++;
    }
 
    // Printing the maximum sum
    Console.WriteLine(sum);
}
 
// Driver code
public static void Main(String[] args)
{
    int []Arr = { 1, 13, 7, 17, 6, 5 };
 
    int K = 2;
 
    int size = Arr.Length;
 
    maximumSum(Arr, size, K);
}
}
 
// This code is contributed by amal kumar choubey


输出:
37


时间复杂度: O(N * logN)
辅助空间: O(1)