📌  相关文章
📜  将数组拆分为K个非空子集,以使它们的最大值和最小值之和最大

📅  最后修改于: 2021-05-06 22:50:34             🧑  作者: Mango

给定两个由NK个整数组成的数组arr []S [] ,任务是在将数组拆分为K个子集后,找到每个子集的最小和最大值的最大和,以使每个子集的大小等于1数组S []中元素的数量。

例子:

方法:可以使用贪婪方法解决给定的问题,其思想是在每个组中插入前K个最大元素,然后开始用较大的元素填充较小的组。请按照以下步骤解决问题:

  • 初始化一个变量,例如ans0 ,以存储所有子集的最大值和最小值之和。
  • 以降序对数组arr []进行排序。
  • 以升序对数组S []进行排序。
  • 找到数组的前K个元素的总和,并将其存储在变量ans中,然后将S []的所有元素减1
  • 初始化一个变量,例如counterK – 1 ,以存储每个子集的最小元素的索引。
  • 遍历数组S []并以S [i]递增计数器,并将arr [counter]的值添加到ans
  • 完成上述步骤后,输出ans的值作为结果。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function find maximum sum of
// minimum and maximum of K subsets
int maximumSum(int arr[], int S[],
               int N, int K)
{
    // Stores the result
    int ans = 0;
 
    // Sort the array arr[] in
    // decreasing order
    sort(arr, arr + N, greater());
 
    // Traverse the range [0, K]
    for (int i = 0; i < K; i++)
        ans += arr[i];
 
    // Sort the array S[] in
    // ascending order
    sort(S, S + K);
 
    // Traverse the array S[]
    for (int i = 0; i < K; i++) {
 
        // If S{i] is 1
        if (S[i] == 1)
            ans += arr[i];
 
        S[i]--;
    }
 
    // Stores the index of the minimum
    // element of the i-th subset
    int counter = K - 1;
 
    // Traverse the array S[]
    for (int i = 0; i < K; i++) {
 
        // Update the counter
        counter = counter + S[i];
 
        if (S[i] != 0)
            ans += arr[counter];
    }
 
    // Return the resultant sum
    return ans;
}
 
// Driver Code
int main()
{
    int arr[] = { 1, 13, 7, 17 };
    int S[] = { 1, 3 };
    int N = sizeof(arr) / sizeof(arr[0]);
    int K = sizeof(S) / sizeof(S[0]);
    cout << maximumSum(arr, S, N, K);
 
    return 0;
}


Java
// Java program for the above approach
import java.io.*;
import java.lang.*;
import java.util.*;
 
class GFG{
 
// Function find maximum sum of
// minimum and maximum of K subsets
static int maximumSum(int arr[], int S[],
                      int N, int K)
{
     
    // Stores the result
    int ans = 0;
 
    // Sort the array arr[] in
    // decreasing order
    Arrays.sort(arr);
    for(int i = 0; i < N / 2; i++)
    {
        int temp = arr[i];
        arr[i] = arr[N - 1 - i];
        arr[N - 1 - i] = temp;
    }
 
    // Traverse the range [0, K]
    for(int i = 0; i < K; i++)
        ans += arr[i];
 
    // Sort the array S[] in
    // ascending order
    Arrays.sort(S);
 
    // Traverse the array S[]
    for(int i = 0; i < K; i++)
    {
         
        // If S{i] is 1
        if (S[i] == 1)
            ans += arr[i];
 
        S[i]--;
    }
 
    // Stores the index of the minimum
    // element of the i-th subset
    int counter = K - 1;
 
    // Traverse the array S[]
    for(int i = 0; i < K; i++)
    {
 
        // Update the counter
        counter = counter + S[i];
 
        if (S[i] != 0)
            ans += arr[counter];
    }
 
    // Return the resultant sum
    return ans;
}
 
// Driver Code
public static void main(String[] args)
{
    int arr[] = { 1, 13, 7, 17 };
    int S[] = { 1, 3 };
    int N = arr.length;
    int K = S.length;
     
    System.out.println(maximumSum(arr, S, N, K));
}
}
 
// This code is contributed by Kingash


输出:
48

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