在所有可能的大小为 K 的子集上找到最大值和最小值之差的总和
给定一个包含N个整数的数组arr[]和一个整数K ,任务是找到 总和 大小为K的所有可能子集的最大和最小元素之间的差异。
例子:
Input: arr[] = {1, 1, 3, 4}, K = 2
Output: 11
Explanation:
There are 6 subsets of the given array of size K(= 2). They are {1, 1}, {1, 3}, {1, 4}, {1, 3}, {1, 4} and {3, 4}.
The values of maximum – minimum for each of the subsets respectively are 0, 2, 3, 2, 3, 1 and their sum is 11.
Input: arr[] = {1, 1, 1}, K = 1
Output: 0
方法:可以根据以下观察解决给定的问题:
- 所有集合的最大值和最小值之差的总和是相互独立的,即它可以计算为所有大小为 K 的集合的最大值之和 - 所有大小为 K 的集合的最小值之和。
- 在排序数组arr[]中, arr[i]是数组中元素在[0, i – 1]范围内的所有集合中的最大值。因此,以 arr[i] 作为最大数组元素的大小为 K 的集合的数量可以计算为 .类似地,以 arr[i] 作为最小元素的大小为 K 的集合的数量是 .
- 的价值可以通过使用本文讨论的方法有效地计算。
使用上述观察,可以通过以下步骤解决给定问题:
- 以非递减顺序对给定数组 arr[] 进行排序。
- 为了计算所有大小K集合的最大值的总和,创建一个变量sumMax ,并为每个[K – 1, N – 1]范围内的索引i迭代数组arr[]并添加进入sumMax 。
- 类似地,为了计算所有大小K集合的最小值的总和,创建一个变量sumMin并且对于范围 [0, NK] 中的每个 i,遍历数组arr[]并添加进入sumMin 。
- sumMax – sumMin的值是要求的答案。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
#define int long long int
#define max 100000
#define mod 1000000007
int inv[max], fact[max], facinv[max];
// Function to precompute factorial and
// the inverse of factorial values of all
// elements in the range [1, max] to find
// the value of nCr in O(1)
void ncrPrecomputation()
{
inv[0] = inv[1] = 1;
fact[0] = fact[1] = 1;
facinv[0] = facinv[1] = 1;
// Loop to iterate over all i in
// the range [2, max]
for (int i = 2; i < max; i++) {
// Calculate Inverse of i
inv[i] = inv[mod % i]
* (mod - mod / i) % mod;
// Calculate Factorial of i
fact[i] = (fact[i - 1] * i) % mod;
// Calculate the Inverse of
// factorial of i
facinv[i] = (inv[i] * facinv[i - 1]) % mod;
}
}
// Function to find nCr in O(1)
int nCr(int n, int r)
{
return ((fact[n] * facinv[r]) % mod
* facinv[n - r])
% mod;
}
// Function to find the sum of difference
// between maximum and minimum over all
// sets of arr[] having K elements
int sumMaxMin(int arr[], int N, int K)
{
// Sort the given array
sort(arr, arr + N);
// Stores the sum of maximum of
// all the sets
int sumMax = 0;
// Loop to iterate arr[] in the
// range [K-1, N-1]
for (int i = K - 1; i < N; i++) {
// Add sum of sets having arr[i]
// as the maximum element
sumMax += (arr[i] * nCr(i, K - 1));
}
// Stores the sum of the minimum of
// all the sets
int sumMin = 0;
// Loop to iterate arr[] in the
// range [0, N - K]
for (int i = 0; i <= N - K; i++) {
// Add sum of sets having arr[i]
// as the minimum element
sumMin += (arr[i] * nCr(N - i - 1, K - 1));
}
// Return answer
return (sumMax - sumMin);
}
// Driver Code
signed main()
{
int arr[] = { 1, 1, 3, 4 };
int K = 2;
int N = sizeof(arr) / sizeof(arr[0]);
ncrPrecomputation();
cout << sumMaxMin(arr, N, K);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
import java.util.*;
class GFG {
static final int max = 100000;
static final int mod = 1000000007;
static long inv[] = new long[max], fact[] = new long[max],
facinv[] = new long[max];
// Function to precompute factorial and
// the inverse of factorial values of all
// elements in the range [1, max] to find
// the value of nCr in O(1)
static void ncrPrecomputation()
{
inv[0] = inv[1] = 1;
fact[0] = fact[1] = 1;
facinv[0] = facinv[1] = 1;
// Loop to iterate over all i in
// the range [2, max]
for (int i = 2; i < max; i++) {
// Calculate Inverse of i
inv[i] = inv[mod % i] * (mod - mod / i) % mod;
// Calculate Factorial of i
fact[i] = (fact[i - 1] * i) % mod;
// Calculate the Inverse of
// factorial of i
facinv[i] = (inv[i] * facinv[i - 1]) % mod;
}
}
// Function to find nCr in O(1)
static long nCr(long n, long r)
{
return ((fact[(int)n] * facinv[(int)r]) % mod * facinv[(int)(n - r)])
% mod;
}
// Function to find the sum of difference
// between maximum and minimum over all
// sets of arr[] having K elements
static long sumMaxMin(long arr[], long N, long K)
{
// Sort the given array
Arrays.sort(arr);
// Stores the sum of maximum of
// all the sets
long sumMax = 0;
// Loop to iterate arr[] in the
// range [K-1, N-1]
for (int i = (int)K - 1; i < N; i++) {
// Add sum of sets having arr[i]
// as the maximum element
sumMax += (arr[i] * nCr(i, K - 1));
}
// Stores the sum of the minimum of
// all the sets
long sumMin = 0;
// Loop to iterate arr[] in the
// range [0, N - K]
for (int i = 0; i <= N - K; i++) {
// Add sum of sets having arr[i]
// as the minimum element
sumMin += (arr[i] * nCr(N - i - 1, K - 1));
}
// Return answer
return (sumMax - sumMin);
}
// Driver Code
public static void main(String[] args)
{
long arr[] = { 1, 1, 3, 4 };
long K = 2;
long N = arr.length;
ncrPrecomputation();
System.out.println(sumMaxMin(arr, N, K));
}
}
// This code is contributed by Dharanendra L V.
C#
// C# program for the above approach
using System;
public class GFG
{
static readonly int max = 100000;
static readonly int mod = 1000000007;
static long []inv = new long[max];
static long []fact = new long[max];
static long []facinv = new long[max];
// Function to precompute factorial and
// the inverse of factorial values of all
// elements in the range [1, max] to find
// the value of nCr in O(1)
static void ncrPrecomputation()
{
inv[0] = inv[1] = 1;
fact[0] = fact[1] = 1;
facinv[0] = facinv[1] = 1;
// Loop to iterate over all i in
// the range [2, max]
for (int i = 2; i < max; i++) {
// Calculate Inverse of i
inv[i] = inv[mod % i] * (mod - mod / i) % mod;
// Calculate Factorial of i
fact[i] = (fact[i - 1] * i) % mod;
// Calculate the Inverse of
// factorial of i
facinv[i] = (inv[i] * facinv[i - 1]) % mod;
}
}
// Function to find nCr in O(1)
static long nCr(long n, long r)
{
return ((fact[(int)n] * facinv[(int)r]) % mod * facinv[(int)(n - r)])
% mod;
}
// Function to find the sum of difference
// between maximum and minimum over all
// sets of []arr having K elements
static long sumMaxMin(long []arr, long N, long K)
{
// Sort the given array
Array.Sort(arr);
// Stores the sum of maximum of
// all the sets
long sumMax = 0;
// Loop to iterate []arr in the
// range [K-1, N-1]
for (int i = (int)K - 1; i < N; i++) {
// Add sum of sets having arr[i]
// as the maximum element
sumMax += (arr[i] * nCr(i, K - 1));
}
// Stores the sum of the minimum of
// all the sets
long sumMin = 0;
// Loop to iterate []arr in the
// range [0, N - K]
for (int i = 0; i <= N - K; i++) {
// Add sum of sets having arr[i]
// as the minimum element
sumMin += (arr[i] * nCr(N - i - 1, K - 1));
}
// Return answer
return (sumMax - sumMin);
}
// Driver Code
public static void Main(String[] args)
{
long []arr = { 1, 1, 3, 4 };
long K = 2;
long N = arr.Length;
ncrPrecomputation();
Console.WriteLine(sumMaxMin(arr, N, K));
}
}
// This code is contributed by 29AjayKumar
Python3
# Python 3 program for the above approach
max1 = 100000
mod = 1000000007
inv = [0 for i in range(max1)]
fact = [0 for i in range(max1)]
facinv = [0 for i in range(max1)]
# Function to precompute factorial and
# the inverse of factorial values of all
# elements in the range [1, max] to find
# the value of nCr in O(1)
def ncrPrecomputation():
inv[0] = inv[1] = 1
fact[0] = fact[1] = 1
facinv[0] = facinv[1] = 1
# Loop to iterate over all i in
# the range [2, max]
for i in range(2,max1,1):
# Calculate Inverse of i
inv[i] = inv[mod % i] * (mod - mod // i) % mod
# Calculate Factorial of i
fact[i] = (fact[i - 1] * i) % mod
# Calculate the Inverse of
# factorial of i
facinv[i] = (inv[i] * facinv[i - 1]) % mod
# Function to find nCr in O(1)
def nCr(n,r):
return ((fact[n] * facinv[r]) % mod * facinv[n - r]) % mod
# Function to find the sum of difference
# between maximum and minimum over all
# sets of arr[] having K elements
def sumMaxMin(arr, N, K):
# Sort the given array
arr.sort()
# Stores the sum of maximum of
# all the sets
sumMax = 0
# Loop to iterate arr[] in the
# range [K-1, N-1]
for i in range(K - 1,N,1):
# Add sum of sets having arr[i]
# as the maximum element
sumMax += (arr[i] * nCr(i, K - 1))
# Stores the sum of the minimum of
# all the sets
sumMin = 0
# Loop to iterate arr[] in the
# range [0, N - K]
for i in range(N - K+1):
# Add sum of sets having arr[i]
# as the minimum element
sumMin += (arr[i] * nCr(N - i - 1, K - 1))
# Return answer
return (sumMax - sumMin)
# Driver Code
if __name__ == '__main__':
arr = [1, 1, 3, 4]
K = 2
N = len(arr)
ncrPrecomputation()
print(sumMaxMin(arr, N, K))
# This code is contributed by SURENDRA_GANGWAR
Javascript
输出:
11
时间复杂度: O(N*log N)
辅助空间: O(N)