# Probability of distributing given balls into two halves having equal count of distinct colors

• Last Updated : 22 Jun, 2021

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.00000

Input: 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++

 `// C++ program for the above approach``#include ``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

 `// 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

 `# 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#

 `// 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`

## Javascript

 ``

Output:

`0.6666666666666666`

Time Complexity: O(N!)
Auxiliary Space: O(1)

My Personal Notes arrow_drop_up