来自前 N 个自然数的所有可能的 K 大小子集的最小值的平均值
给定两个正整数N和K ,任务是从前N个自然数中找到大小为 K的所有可能子集的最小值的平均值。
例子:
Input: N = 3, K = 2
Output: 1.33333
Explanation:
All possible subsets of size K are {1, 2}, {1, 3}, {2, 3}. The minimum values in all the subsets are 1, 1, and 2 respectively. The mean of all the minimum values is (1 + 1 + 2)/3 = 1.3333.
Input: N = 3, K = 1
Output: 2.00000
朴素方法:解决给定问题的最简单方法是找到由元素[1, N]形成的所有子集,并找到大小为K的子集的所有最小元素的平均值。
时间复杂度: O(N*2 N )
辅助空间: O(1)
高效方法:上述方法也可以通过观察以下事实来优化:由大小 K形成的子集的总数由N C K给出,并且每个元素说i出现(N – i) C (K – 1)次作为最小元素。
因此,我们的想法是在 i 的所有可能值上找到( N – i C K – 1) )*i的总和,然后将其除以形成的子集的总数,即N C K。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the value of nCr
int nCr(int n, int r, int f[])
{
// Base Case
if (n < r) {
return 0;
}
// Find nCr recursively
return f[n] / (f[r] * f[n - r]);
}
// Function to find the expected minimum
// values of all the subsets of size K
int findMean(int N, int X)
{
// Find the factorials that will
// be used later
int f[N + 1];
f[0] = 1;
// Find the factorials
for (int i = 1; i <= N; i++) {
f[i] = f[i - 1] * i;
}
// Total number of subsets
int total = nCr(N, X, f);
// Stores the sum of minimum over
// all possible subsets
int count = 0;
// Iterate over all possible minimum
for (int i = 1; i <= N; i++) {
count += nCr(N - i, X - 1, f) * i;
}
// Find the mean over all subsets
double E_X = double(count) / double(total);
cout << setprecision(10) << E_X;
return 0;
}
// Driver Code
int main()
{
int N = 3, X = 2;
findMean(N, X);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG {
// Function to find the value of nCr
static int nCr(int n, int r, int f[]) {
// Base Case
if (n < r) {
return 0;
}
// Find nCr recursively
return f[n] / (f[r] * f[n - r]);
}
// Function to find the expected minimum
// values of all the subsets of size K
static int findMean(int N, int X) {
// Find the factorials that will
// be used later
int[] f = new int[N + 1];
f[0] = 1;
// Find the factorials
for (int i = 1; i <= N; i++) {
f[i] = f[i - 1] * i;
}
// Total number of subsets
int total = nCr(N, X, f);
// Stores the sum of minimum over
// all possible subsets
int count = 0;
// Iterate over all possible minimum
for (int i = 1; i <= N; i++) {
count += nCr(N - i, X - 1, f) * i;
}
// Find the mean over all subsets
double E_X = (double) (count) / (double) (total);
System.out.print(String.format("%.6f", E_X));
return 0;
}
// Driver Code
public static void main(String[] args) {
int N = 3, X = 2;
findMean(N, X);
}
}
// This code contributed by Princi Singh
Python3
# Python 3 program for the above approach
# Function to find the value of nCr
def nCr(n, r, f):
# Base Case
if (n < r):
return 0
# Find nCr recursively
return f[n] / (f[r] * f[n - r])
# Function to find the expected minimum
# values of all the subsets of size K
def findMean(N, X):
# Find the factorials that will
# be used later
f = [0 for i in range(N + 1)]
f[0] = 1
# Find the factorials
for i in range(1,N+1,1):
f[i] = f[i - 1] * i
# Total number of subsets
total = nCr(N, X, f)
# Stores the sum of minimum over
# all possible subsets
count = 0
# Iterate over all possible minimum
for i in range(1,N+1,1):
count += nCr(N - i, X - 1, f) * i
# Find the mean over all subsets
E_X = (count) / (total)
print("{0:.9f}".format(E_X))
return 0
# Driver Code
if __name__ == '__main__':
N = 3
X = 2
findMean(N, X)
# This code is contributed by ipg201607.
C#
// C# code for the above approach
using System;
public class GFG
{
// Function to find the value of nCr
static int nCr(int n, int r, int[] f)
{
// Base Case
if (n < r) {
return 0;
}
// Find nCr recursively
return f[n] / (f[r] * f[n - r]);
}
// Function to find the expected minimum
// values of all the subsets of size K
static int findMean(int N, int X)
{
// Find the factorials that will
// be used later
int[] f = new int[N + 1];
f[0] = 1;
// Find the factorials
for (int i = 1; i <= N; i++) {
f[i] = f[i - 1] * i;
}
// Total number of subsets
int total = nCr(N, X, f);
// Stores the sum of minimum over
// all possible subsets
int count = 0;
// Iterate over all possible minimum
for (int i = 1; i <= N; i++) {
count += nCr(N - i, X - 1, f) * i;
}
// Find the mean over all subsets
double E_X = (double) (count) / (double) (total);
Console.Write("{0:F9}", E_X);
return 0;
}
// Driver Code
static public void Main (){
// Code
int N = 3, X = 2;
findMean(N, X);
}
}
// This code is contributed by Potta Lokesh
Javascript
输出:
1.333333333
时间复杂度: O(N)
辅助空间: O(N)