给定一个由N个整数元素组成的数组arr,任务是找到该数组所有子集的平均值之和。
例子 :
Input : arr[] = [2, 3, 5]
Output : 23.33
Explanation : Subsets with their average are,
[2] average = 2/1 = 2
[3] average = 3/1 = 3
[5] average = 5/1 = 5
[2, 3] average = (2+3)/2 = 2.5
[2, 5] average = (2+5)/2 = 3.5
[3, 5] average = (3+5)/2 = 4
[2, 3, 5] average = (2+3+5)/3 = 3.33
Sum of average of all subset is,
2 + 3 + 5 + 2.5 + 3.5 + 4 + 3.33 = 23.33
一个幼稚的解决方案是遍历所有可能的子集,获取所有子集的平均值,然后将它们一个接一个地添加,但是这将花费指数时间,并且对于较大的数组将是不可行的。
我们可以举个例子,
arr = [a0, a1, a2, a3]
sum of average =
a0/1 + a1/1 + a2/2 + a3/1 +
(a0+a1)/2 + (a0+a2)/2 + (a0+a3)/2 + (a1+a2)/2 +
(a1+a3)/2 + (a2+a3)/2 +
(a0+a1+a2)/3 + (a0+a2+a3)/3 + (a0+a1+a3)/3 +
(a1+a2+a3)/3 +
(a0+a1+a2+a3)/4
If S = (a0+a1+a2+a3), then above expression
can be rearranged as below,
sum of average = (S)/1 + (3*S)/2 + (3*S)/3 + (S)/4
分子的系数可以解释如下,假设我们对K个元素的子集进行迭代,则分母为K,分子为r * S,其中“ r”表示在迭代时添加特定数组元素的次数。大小相同的子集。通过检查,我们可以看到r为nCr(N – 1,n – 1),因为在求和一个元素后,我们需要从(N – 1)个元素中选择(n – 1)个元素,因此每个元素都有一个当考虑相同大小的子集时,nCr(N – 1,n – 1)的频率,因为所有元素都参加相等的次数,这也将是S的频率,并且将成为最终表达式中的分子。
在下面的代码中,nCr是使用动态编程方法实现的,您可以在此处了解更多信息,
C++
// C++ program to get sum of average of all subsets
#include
using namespace std;
// Returns value of Binomial Coefficient C(n, k)
int nCr(int n, int k)
{
int C[n + 1][k + 1];
int i, j;
// Calculate value of Binomial Coefficient in bottom
// up manner
for (i = 0; i <= n; i++) {
for (j = 0; j <= min(i, k); j++) {
// Base Cases
if (j == 0 || j == i)
C[i][j] = 1;
// Calculate value using previously stored
// values
else
C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
}
}
return C[n][k];
}
// method returns sum of average of all subsets
double resultOfAllSubsets(int arr[], int N)
{
double result = 0.0; // Initialize result
// Find sum of elements
int sum = 0;
for (int i = 0; i < N; i++)
sum += arr[i];
// looping once for all subset of same size
for (int n = 1; n <= N; n++)
/* each element occurs nCr(N-1, n-1) times while
considering subset of size n */
result += (double)(sum * (nCr(N - 1, n - 1))) / n;
return result;
}
// Driver code to test above methods
int main()
{
int arr[] = { 2, 3, 5, 7 };
int N = sizeof(arr) / sizeof(int);
cout << resultOfAllSubsets(arr, N) << endl;
return 0;
}
Java
// java program to get sum of
// average of all subsets
import java.io.*;
class GFG {
// Returns value of Binomial
// Coefficient C(n, k)
static int nCr(int n, int k)
{
int C[][] = new int[n + 1][k + 1];
int i, j;
// Calculate value of Binomial
// Coefficient in bottom up manner
for (i = 0; i <= n; i++) {
for (j = 0; j <= Math.min(i, k); j++) {
// Base Cases
if (j == 0 || j == i)
C[i][j] = 1;
// Calculate value using
// previously stored values
else
C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
}
}
return C[n][k];
}
// method returns sum of average of all subsets
static double resultOfAllSubsets(int arr[], int N)
{
// Initialize result
double result = 0.0;
// Find sum of elements
int sum = 0;
for (int i = 0; i < N; i++)
sum += arr[i];
// looping once for all subset of same size
for (int n = 1; n <= N; n++)
/* each element occurs nCr(N-1, n-1) times while
considering subset of size n */
result += (double)(sum * (nCr(N - 1, n - 1))) / n;
return result;
}
// Driver code to test above methods
public static void main(String[] args)
{
int arr[] = { 2, 3, 5, 7 };
int N = arr.length;
System.out.println(resultOfAllSubsets(arr, N));
}
}
// This code is contributed by vt_m
Python3
# Python3 program to get sum
# of average of all subsets
# Returns value of Binomial
# Coefficient C(n, k)
def nCr(n, k):
C = [[0 for i in range(k + 1)]
for j in range(n + 1)]
# Calculate value of Binomial
# Coefficient in bottom up manner
for i in range(n + 1):
for j in range(min(i, k) + 1):
# Base Cases
if (j == 0 or j == i):
C[i][j] = 1
# Calculate value using
# previously stored values
else:
C[i][j] = C[i-1][j-1] + C[i-1][j]
return C[n][k]
# Method returns sum of
# average of all subsets
def resultOfAllSubsets(arr, N):
result = 0.0 # Initialize result
# Find sum of elements
sum = 0
for i in range(N):
sum += arr[i]
# looping once for all subset of same size
for n in range(1, N + 1):
# each element occurs nCr(N-1, n-1) times while
# considering subset of size n */
result += (sum * (nCr(N - 1, n - 1))) / n
return result
# Driver code
arr = [2, 3, 5, 7]
N = len(arr)
print(resultOfAllSubsets(arr, N))
# This code is contributed by Anant Agarwal.
C#
// C# program to get sum of
// average of all subsets
using System;
class GFG {
// Returns value of Binomial
// Coefficient C(n, k)
static int nCr(int n, int k)
{
int[, ] C = new int[n + 1, k + 1];
int i, j;
// Calculate value of Binomial
// Coefficient in bottom up manner
for (i = 0; i <= n; i++) {
for (j = 0; j <= Math.Min(i, k); j++)
{
// Base Cases
if (j == 0 || j == i)
C[i, j] = 1;
// Calculate value using
// previously stored values
else
C[i, j] = C[i - 1, j - 1] + C[i - 1, j];
}
}
return C[n, k];
}
// method returns sum of average
// of all subsets
static double resultOfAllSubsets(int[] arr, int N)
{
// Initialize result
double result = 0.0;
// Find sum of elements
int sum = 0;
for (int i = 0; i < N; i++)
sum += arr[i];
// looping once for all subset
// of same size
for (int n = 1; n <= N; n++)
/* each element occurs nCr(N-1, n-1) times while
considering subset of size n */
result += (double)(sum * (nCr(N - 1, n - 1))) / n;
return result;
}
// Driver code to test above methods
public static void Main()
{
int[] arr = { 2, 3, 5, 7 };
int N = arr.Length;
Console.WriteLine(resultOfAllSubsets(arr, N));
}
}
// This code is contributed by Sam007
PHP
输出 :
63.75