📜  将给定数组分配到 K 个集合中,使得所有集合的最大和最小元素的总和最大

📅  最后修改于: 2022-05-13 01:57:50.789000             🧑  作者: Mango

将给定数组分配到 K 个集合中,使得所有集合的最大和最小元素的总和最大

给定两个数组,第一个arr[]大小为N ,第二个brr[]大小为K 。任务是将第一个数组arr[]分成K个集合,使得第i 个集合应该包含来自第二个数组brr[]brr[i]元素,并且所有集合的最大和最小元素的总和最大.

例子:

方法:将最大元素设置为 size = 1。其余的,对数组进行排序, arr[]按降序排序, brr[]按升序排序。现在,如果集合的大小不是 1,则将最小元素添加到答案中。请按照以下步骤解决问题:

  • 对数组进行排序, arr[]按降序排列, brr[]按升序排列。
  • 将变量 say ans初始化为0以存储答案的值,并将cnt初始化为0以计算大小为 1 的集合的数量。
  • [0, K]范围内迭代并计算大小为 1 的集合数并将值存储在变量cnt 中。
  • [0, K]范围内迭代并执行以下步骤。
    • arr[i]的值添加到变量ans中,因为arr[i]的值将是第i 个集合的最大值。
    • 如果cnt的值大于 0,则将arr[i]的值再次相加,因为它也是最小值,然后将cnt的值减 1。
  • 将变量from初始化为K以维护计数器。
  • [0, K]范围内迭代并执行以下步骤。
    • 如果brr[i]的值为1,则继续。
    • arr[from + brr[i] – 2]的值添加到答案中。
    • from的值增加brr[i]-1。
  • 打印答案的最终值。

下面是上述方法的实现。

C++
// C++ program for the above approach
#include 
using namespace std;
 
typedef long long ll;
 
// Function to find K sets such that the
// sum of maximum and minimum of all sets
// is maximum
void findSets(int n, int k, vector& arr,
              vector& brr)
{
    ll ans = 0;
 
    // Sort both the arrays
    // arr[] in descending order.
    // brr[] in ascending order.
    sort(arr.begin(), arr.end());
    sort(brr.begin(), brr.end());
    reverse(arr.begin(), arr.end());
 
    int cnt = 0;
 
    // Count the number of sets with size 1
    for (int& v : brr) {
        if (v == 1)
            cnt++;
    }
 
    // Assign the first K maximum elements
    // to the sets and add them as minimum
    // also for sets with size 1.
    for (int i = 0; i < k; i++) {
        ans += arr[i];
        if (cnt > 0) {
            ans += arr[i];
            cnt--;
        }
    }
 
    int from = k;
    // Add the minimum element from the set.
    for (int i = 0; i < k; i++) {
        if (brr[i] == 1)
            continue;
        ans += arr[from + brr[i] - 2];
        from += brr[i] - 1;
    }
 
    cout << ans << '\n';
}
 
// Driver Code
int main()
{
    int n, k;
 
    n = 4;
    k = 2;
 
    vector arr{ 10, 10, 11, 11 };
    vector brr{ 2, 2 };
 
    findSets(n, k, arr, brr);
 
    return 0;
}


Java
import java.util.Arrays;
import java.util.Collections;
 
// C++ program for the above approach
class GFG {
 
    // Function to find K sets such that the
    // sum of maximum and minimum of all sets
    // is maximum
    public static void findSets(int n, int k, int[] arr, int[] brr) {
        int ans = 0;
 
        // Sort both the arrays
        // arr[] in descending order.
        // brr[] in ascending order.
        Arrays.sort(arr);
        Arrays.sort(brr);
 
        Collections.reverse(Arrays.asList(arr));
 
        int cnt = 0;
 
        // Count the number of sets with size 1
        for (int v : brr) {
            if (v == 1)
                cnt++;
        }
 
        // Assign the first K maximum elements
        // to the sets and add them as minimum
        // also for sets with size 1.
        for (int i = 0; i < k; i++) {
            ans += arr[i];
            if (cnt > 0) {
                ans += arr[i];
                cnt--;
            }
        }
 
        int from = k;
        // Add the minimum element from the set.
        for (int i = 0; i < k; i++) {
            if (brr[i] == 1)
                continue;
            ans += arr[from + brr[i] - 2];
            from += brr[i] - 1;
        }
 
        System.out.println(ans);
    }
 
    // Driver Code
    public static void main(String args[]) {
        int n, k;
 
        n = 4;
        k = 2;
 
        int[] arr = { 10, 10, 11, 11 };
        int[] brr = { 2, 2 };
 
        findSets(n, k, arr, brr);
 
    }
 
}
 
// This code is contributed by gfgking.


Python3
# python 3 program for the above approach
# Function to find K sets such that the
# sum of maximum and minimum of all sets
# is maximum
def findSets(n, k, arr, brr):
    ans = 0
 
    # Sort both the arrays
    # arr[] in descending order.
    # brr[] in ascending order.
    arr.sort()
    brr.sort()
    arr = arr[:-1]
 
    cnt = 0
 
    # Count the number of sets with size 1
    for v in brr:
        if (v == 1):
            cnt += 1
 
    # Assign the first K maximum elements
    # to the sets and add them as minimum
    # also for sets with size 1.
    for i in range(k):
        ans += arr[i]
        if (cnt > 0):
            ans += arr[i]
            cnt -= 1
 
    from1 = k
    # Add the minimum element from the set.
    for i in range(k):
        if (brr[i] == 1):
            continue
        if from1 + brr[i] - 2>len(arr)-1:
            continue;
        ans += arr[from1 + brr[i] - 2]
        from1 += brr[i] - 1
 
    print(ans)
 
# Driver Code
if __name__ == '__main__':
    n = 4
    k = 2
 
    arr =  [10, 10, 11, 11]
    brr =  [2, 2]
    findSets(n, k, arr, brr)


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG{
 
// Function to find K sets such that the
// sum of maximum and minimum of all sets
// is maximum
static void findSets(int n, int k, List arr,
              List brr)
{
    int ans = 0;
 
    // Sort both the arrays
    // arr[] in descending order.
    // brr[] in ascending order.
    arr.Sort();
    brr.Sort();
    arr.Reverse();
 
    int cnt = 0;
 
    // Count the number of sets with size 1
    foreach (int v in brr) {
        if (v == 1)
            cnt++;
    }
 
    // Assign the first K maximum elements
    // to the sets and add them as minimum
    // also for sets with size 1.
    for (int i = 0; i < k; i++) {
        ans += arr[i];
        if (cnt > 0) {
            ans += arr[i];
            cnt--;
        }
    }
 
    int from = k;
    // Add the minimum element from the set.
    for (int i = 0; i < k; i++) {
        if (brr[i] == 1)
            continue;
        ans += arr[from + brr[i] - 2];
        from += brr[i] - 1;
    }
 
    Console.Write(ans);
}
 
// Driver Code
public static void Main()
{
    int n, k;
 
    n = 4;
    k = 2;
 
    List arr = new List(){ 10, 10, 11, 11 };
    List brr = new List(){ 2, 2 };
 
    findSets(n, k, arr, brr);
}
}
 
// This code is contributed by SURENDRA_GANGWAR.


Javascript


输出
42

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