Given an array arr[] of size N, representing the number of balls of each of N distinct colors, the task is to find the probability of distributing all the balls into two boxes, such that both the boxes contain an equal number of distinct colored balls.
Examples:
Input: arr[] = {1, 1}, N = 2
Output: 1.00000
Explanation: Two possible ways to distribute them are as follows:
Put the ball of 0th color type in the 1st box and the ball of 1st color type into the 2nd box.
Put the color of 1st type in the 1st box and the color of 0th type in the 2nd box.
Therefore, the probability is equal to (2 / 2) = 1.00000Input: arr[] = {2, 1, 1}, N = 3
Output: 0.66667
Approach: The idea is to use combinatorics and backtracking to solve the problem. The given problem can be solved based on the following observations:
- Suppose X is the total number of ways to distribute K balls into two equal halves.
- It can be observed that X is the same as choosing K/2 balls from the K balls, which is equal to KC(K/2).
- The total number of ways of distributing the balls such that both the boxes contain the same number of balls and same number of total distinct colors, say Y, can be calculated using Backtracking, by choosing j balls from the arr[i] and putting it in a box for every 0 ? i < N and j ? arr[i], and place the remaining balls in the other box.
- Therefore, the required probability is Y/X.
Follow the steps below to solve the problem:
- Calculate the sum of all elements present in the array arr[] in a variable, say K.
- Print 0 if K is an odd number.
- Calculate the number of ways of selecting K/2 balls and store it in a variable, say X.
- Define a recursive function, say validPermutations(pos, usedBalls, box1, box2), and perform the following steps:
- Define the base case: If usedBalls is equal to K/2, then return 1 if box1 = box2. Otherwise, return 0.
- If pos ? N, then return 0.
- Now, initialize a variable, say res, to store the number of ways of distributing the remaining balls.
- Iterate over the range [0, arr[pos]]:
- Assign box1, and box2 to variables, say newbox1 and newbox2 respectively.
- Increment newbox1 by one if j > 0 and newbox2, if j < arr[pos].
- Now, update res as res = res + arr[pos]Cj * validPermutations(pos+1, usedBalls+j, newbox1, newbox2).
- Return the value of res.
- Call the function validPermutations(0, 0, 0, 0) and store it in a variable, say Y.
- Finally, print the result obtained as Y/X.
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
// Stores the count of // distinct colors in box1 static int box1 = 0;
// Stores the count of // distinct colors in box2 static int box2 = 0;
static int fact[11];
// Function to calculate NcR long comb( int n, int r)
{ long res = fact[n] / fact[r];
res /= fact[n - r];
return res;
} // Function to calculate factorial of N void factorial( int N)
{ // Base Case
fact[0] = 1;
// Iterate over the range [1, N]
for ( int i = 1; i <= N; i++)
fact[i] = fact[i - 1] * i;
} // Function to calculate total number // of possible distributions which // satisfies the given conditions long validPermutations( int n, int balls[],
int usedBalls,
int i, int M)
{ // If used balls is equal to K/2
if (usedBalls == n)
{
// If box1 is equal to box2
return box1 == box2 ? 1 : 0;
}
// Base condition
if (i >= M)
return 0;
// Stores the number of ways of
// distributing remaining balls without
// including the current balls in box1
long res = validPermutations(n, balls,
usedBalls,
i + 1, M);
// Increment box1 by one
box1++;
// Iterate over the range [1, balls[i]]
for ( int j = 1; j <= balls[i]; j++)
{
// If all the balls goes to box1,
// then decrease box2 by one
if (j == balls[i])
box2--;
// Total number of ways of
// selecting j balls
long combinations = comb(balls[i], j);
// Increment res by total number of valid
// ways of distributing the remaining balls
res += combinations * validPermutations(n, balls,
usedBalls + j,
i + 1, M);
}
// Decrement box1 by one
box1--;
// Increment box2 by 1
box2++;
return res;
} // Function to calculate the required probability double getProbability( int balls[], int M)
{ // Calculate factorial from [1, 10]
factorial(10);
// Assign all distinct balls to second box
box2 = M;
// Total number of balls
int K = 0;
// Calculate total number of balls
for ( int i = 0; i < M; i++)
K += balls[i];
// If K is an odd number
if (K % 2 == 1)
return 0;
// Total ways of distributing the balls
// in two equal halves
long all = comb(K, K / 2);
// Required number of ways
long validPermutation = validPermutations(K / 2, balls,
0, 0, M);
// Return the required probability
return ( double )validPermutation / all;
} // Driver Code int main()
{ int arr[] = { 2, 1, 1 };
int N = 4;
int M = sizeof (arr) / sizeof (arr[0]);
// Print the result
cout << (getProbability(arr, M));
return 0;
} // This code is contributed by ukasp |
// Java program for the above approach import java.io.*;
import java.util.*;
class GFG {
// Stores the count of
// distinct colors in box1
static int box1 = 0 ;
// Stores the count of
// distinct colors in box2
static int box2 = 0 ;
static int [] fact = new int [ 11 ];
// Function to calculate the required probability
public static double getProbability( int [] balls)
{
// Calculate factorial from [1, 10]
factorial( 10 );
// Assign all distinct balls to second box
box2 = balls.length;
// Total number of balls
int K = 0 ;
// Calculate total number of balls
for ( int i = 0 ; i < balls.length; i++)
K += balls[i];
// If K is an odd number
if (K % 2 == 1 )
return 0 ;
// Total ways of distributing the balls
// in two equal halves
long all = comb(K, K / 2 );
// Required number of ways
long validPermutations = validPermutations(K / 2 , balls, 0 , 0 );
// Return the required probability
return ( double )validPermutations / all;
}
// Function to calculate total number
// of possible distributions which
// satisfies the given conditions
static long validPermutations( int n, int [] balls,
int usedBalls, int i)
{
// If used balls is equal to K/2
if (usedBalls == n) {
// If box1 is equal to box2
return box1 == box2 ? 1 : 0 ;
}
// Base condition
if (i >= balls.length)
return 0 ;
// Stores the number of ways of
// distributing remaining balls without
// including the current balls in box1
long res = validPermutations(n, balls, usedBalls, i + 1 );
// Increment box1 by one
box1++;
// Iterate over the range [1, balls[i]]
for ( int j = 1 ; j <= balls[i]; j++) {
// If all the balls goes to box1,
// then decrease box2 by one
if (j == balls[i])
box2--;
// Total number of ways of
// selecting j balls
long combinations = comb(balls[i], j);
// Increment res by total number of valid
// ways of distributing the remaining balls
res += combinations * validPermutations(n, balls,
usedBalls + j, i + 1 );
}
// Decrement box1 by one
box1--;
// Increment box2 by 1
box2++;
return res;
}
// Function to calculate factorial of N
static void factorial( int N)
{
// Base Case
fact[ 0 ] = 1 ;
// Iterate over the range [1, N]
for ( int i = 1 ; i <= N; i++)
fact[i] = fact[i - 1 ] * i;
}
// Function to calculate NcR
static long comb( int n, int r)
{
long res = fact[n] / fact[r];
res /= fact[n - r];
return res;
}
// Driver Code
public static void main(String[] args)
{
int [] arr = { 2 , 1 , 1 };
int N = 4 ;
// Print the result
System.out.println(getProbability(arr));
}
} |
# Python3 program for the above approach # Stores the count of # distinct colors in box1 box1 = 0
# Stores the count of # distinct colors in box2 box2 = 0
fact = [ 0 for i in range ( 11 )]
# Function to calculate the required probability def getProbability(balls):
global box1, box2, fact
# Calculate factorial from [1, 10]
factorial( 10 )
# Assign all distinct balls to second box
box2 = len (balls)
# Total number of balls
K = 0
# Calculate total number of balls
for i in range ( len (balls)):
K + = balls[i]
# If K is an odd number
if (K % 2 = = 1 ):
return 0
# Total ways of distributing the balls
# in two equal halves
all = comb(K, K / / 2 )
# Required number of ways
validPermutation = validPermutations(
K / / 2 , balls, 0 , 0 )
# Return the required probability
return validPermutation / all
# Function to calculate total number # of possible distributions which # satisfies the given conditions def validPermutations(n, balls, usedBalls, i):
global box1, box2, fact
# If used balls is equal to K/2
if (usedBalls = = n):
# If box1 is equal to box2
if (box1 = = box2):
return 1
else :
return 0
# Base condition
if (i > = len (balls)):
return 0
# Stores the number of ways of
# distributing remaining balls without
# including the current balls in box1
res = validPermutations(n, balls,
usedBalls, i + 1 )
# Increment box1 by one
box1 + = 1
# Iterate over the range [1, balls[i]]
for j in range ( 1 , balls[i] + 1 ):
# If all the balls goes to box1,
# then decrease box2 by one
if (j = = balls[i]):
box2 - = 1
# Total number of ways of
# selecting j balls
combinations = comb(balls[i], j)
# Increment res by total number of valid
# ways of distributing the remaining balls
res + = combinations * validPermutations(n, balls,
usedBalls + j,
i + 1 )
# Decrement box1 by one
box1 - = 1
# Increment box2 by 1
box2 + = 1
return res
# Function to calculate factorial of N def factorial(N):
global box1, box2, fact
# Base Case
fact[ 0 ] = 1
# Iterate over the range [1, N]
for i in range ( 1 , N + 1 ):
fact[i] = fact[i - 1 ] * i
# Function to calculate NcR def comb(n, r):
global box1, box2, fact
res = fact[n] / / fact[r]
res / / = fact[n - r]
return res
# Driver Code arr = [ 2 , 1 , 1 ]
N = 4
print (getProbability(arr))
# This code is contributed by avanitrachhadiya2155 |
// C# program for the above approach using System;
public class GFG
{ // Stores the count of
// distinct colors in box1
static int box1 = 0;
// Stores the count of
// distinct colors in box2
static int box2 = 0;
static int [] fact = new int [11];
// Function to calculate the required probability
public static double getProbability( int [] balls)
{
// Calculate factorial from [1, 10]
factorial(10);
// Assign all distinct balls to second box
box2 = balls.Length;
// Total number of balls
int K = 0;
// Calculate total number of balls
for ( int i = 0; i < balls.Length; i++)
K += balls[i];
// If K is an odd number
if (K % 2 == 1)
return 0;
// Total ways of distributing the balls
// in two equal halves
long all = comb(K, K / 2);
// Required number of ways
long validPermutationss = validPermutations((K / 2), balls, 0, 0);
// Return the required probability
return ( double )validPermutationss / all;
}
// Function to calculate total number
// of possible distributions which
// satisfies the given conditions
static long validPermutations( int n, int [] balls,
int usedBalls, int i)
{
// If used balls is equal to K/2
if (usedBalls == n)
{
// If box1 is equal to box2
return box1 == box2 ? 1 : 0;
}
// Base condition
if (i >= balls.Length)
return 0;
// Stores the number of ways of
// distributing remaining balls without
// including the current balls in box1
long res = validPermutations(n, balls, usedBalls, i + 1);
// Increment box1 by one
box1++;
// Iterate over the range [1, balls[i]]
for ( int j = 1; j <= balls[i]; j++)
{
// If all the balls goes to box1,
// then decrease box2 by one
if (j == balls[i])
box2--;
// Total number of ways of
// selecting j balls
long combinations = comb(balls[i], j);
// Increment res by total number of valid
// ways of distributing the remaining balls
res += combinations * validPermutations(n, balls,
usedBalls + j, i + 1);
}
// Decrement box1 by one
box1--;
// Increment box2 by 1
box2++;
return res;
}
// Function to calculate factorial of N
static void factorial( int N)
{
// Base Case
fact[0] = 1;
// Iterate over the range [1, N]
for ( int i = 1; i <= N; i++)
fact[i] = fact[i - 1] * i;
}
// Function to calculate NcR
static long comb( int n, int r)
{
long res = fact[n] / fact[r];
res /= fact[n - r];
return res;
}
// Driver Code
public static void Main(String[] args)
{
int [] arr = { 2, 1, 1 };
int N = 4;
// Print the result
Console.WriteLine(getProbability(arr));
}
} // This code is contributed by 29AjayKumar |
<script> // Javascript program for the above approach // Stores the count of // distinct colors in box1 var box1 = 0;
// Stores the count of // distinct colors in box2 var box2 = 0;
var fact = Array(11);
// Function to calculate NcR function comb(n, r)
{ var res = fact[n] / fact[r];
res /= fact[n - r];
return res;
} // Function to calculate factorial of N function factorial(N)
{ // Base Case
fact[0] = 1;
// Iterate over the range [1, N]
for ( var i = 1; i <= N; i++)
fact[i] = fact[i - 1] * i;
} // Function to calculate total number // of possible distributions which // satisfies the given conditions function validPermutations(n, balls,usedBalls, i, M)
{ // If used balls is equal to K/2
if (usedBalls == n)
{
// If box1 is equal to box2
return box1 == box2 ? 1 : 0;
}
// Base condition
if (i >= M)
return 0;
// Stores the number of ways of
// distributing remaining balls without
// including the current balls in box1
var res = validPermutations(n, balls,
usedBalls,
i + 1, M);
// Increment box1 by one
box1++;
// Iterate over the range [1, balls[i]]
for ( var j = 1; j <= balls[i]; j++)
{
// If all the balls goes to box1,
// then decrease box2 by one
if (j == balls[i])
box2--;
// Total number of ways of
// selecting j balls
var combinations = comb(balls[i], j);
// Increment res by total number of valid
// ways of distributing the remaining balls
res += combinations * validPermutations(n, balls,
usedBalls + j,
i + 1, M);
}
// Decrement box1 by one
box1--;
// Increment box2 by 1
box2++;
return res;
} // Function to calculate the required probability function getProbability(balls, M)
{ // Calculate factorial from [1, 10]
factorial(10);
// Assign all distinct balls to second box
box2 = M;
// Total number of balls
var K = 0;
// Calculate total number of balls
for ( var i = 0; i < M; i++)
K += balls[i];
// If K is an odd number
if (K % 2 == 1)
return 0;
// Total ways of distributing the balls
// in two equal halves
var all = comb(K, K / 2);
// Required number of ways
var validPermutation = validPermutations(K / 2, balls,
0, 0, M);
// Return the required probability
return validPermutation / all;
} // Driver Code var arr = [2, 1, 1];
var N = 4;
var M = arr.length;
// Print the result document.write(getProbability(arr, M)); </script> |
0.6666666666666666
Time Complexity: O(N!)
Auxiliary Space: O(1)