将给定数组分配到 K 个集合中,使得所有集合的最大和最小元素的总和最大
给定两个数组,第一个arr[]大小为N ,第二个brr[]大小为K 。任务是将第一个数组arr[]分成K个集合,使得第i 个集合应该包含来自第二个数组brr[]的brr[i]元素,并且所有集合的最大和最小元素的总和最大.
例子:
Input: n = 4, k = 2, arr[] = {10, 10, 11, 11 }, brr[] = {2, 2 }
Output: 42
Explanation: First set = 10 11, sum of maximum and minimum = 21, Second set = 10 11, sum of maximum and minimum = 21. Total sum = 42 (maximum possible)
Input: n = 4, k = 4, arr[] = {10, 10, 10, 10}, brr[] = {1, 1, 1, 1 }
Output: 42
方法:将最大元素设置为 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)