给定一个大小为N的数组arr[] ,代表N 种不同颜色的球的数量,任务是找到将所有球分布到两个盒子中的概率,这样两个盒子都包含相同数量的不同颜色球。
例子:
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
方法:这个想法是使用组合学和回溯来解决问题。可以根据以下观察解决给定的问题:
- 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.
请按照以下步骤解决问题:
- 计算一个变量数组arr[]中所有元素的总和,比如K。
- 如果K是奇数,则打印0 。
- 计算选择K/2 个球的方式数并将其存储在变量中,例如X 。
- 定义一个递归函数,比如validPermutations(pos, usedBalls, box1, box2) ,并执行以下步骤:
- 定义基本情况:如果usedBalls等于K/2 ,则在box1 = box2 时返回1 。否则,返回0 。
- 如果pos ≥ N ,则返回0 。
- 现在,初始化一个变量,例如res ,以存储分配剩余球的方式数。
- 迭代范围[0, arr[pos]]:
- 将box1和box2分配给变量,分别说newbox1和newbox2 。
- 如果j > 0和newbox2 ,如果j < arr[pos] ,则将newbox1加一。
- 现在,更新资源作为解析度= RES + ARR [POS]ÇĴ* validPermutations(位置+ 1,usedBalls + J,newbox1,newbox2)。
- 返回res的值。
- 调用函数validPermutations(0, 0, 0, 0)并将其存储在一个变量中,比如Y。
- 最后,将获得的结果打印为Y/X 。
下面是上述方法的实现:
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));
}
}
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
输出:
0.6666666666666666
时间复杂度: O(N!)
辅助空间: O(1)