Count ways of selecting X red balls and Y blue balls
Given integers A, B, C, and D, There are two boxes First Box has A red balls and B blue balls and the second box has C red balls and D blue balls, the task is to count ways to select 3 red balls and 3 blue balls so that there are 3 balls drawn from the first box and 3 balls drawn from the second box. (Print the answer modulo 109 + 7).
Examples:
Input: A = 4, B =3, C = 3, D = 4
Output: 485Input: A = 3, B = 3, C = 3, D = 3
Output: 164
Naive approach: The basic way to solve the problem is as follows:
The basic way to solve this problem is to generate all possible combinations by using a recursive approach.
Time Complexity: O(N!)
Auxiliary Space: O(1)
Efficient Approach: The above approach can be optimized based on the following idea:
The problem can be solved with combinatorics:
Case 1: 2 red balls and 1 blue ball from box 1 and 1 red ball and 2 blue balls from box 2.
- Total ways of case1 = AC2 * BC1 * CC1 * DC2
Case 2: 3 red balls from box 1 and 3 blue balls from box 2.
- Total ways of case2 = AC3 * DC3
Case 3: 3 blue balls from box1 and 3 red balls from box 2
- Total ways of case3 = BC3 * CC3
Case 4: 1 red ball and 2 blue balls from box 1 and 2 red balls and 1 blue ball from box 2.
- Total ways of case4 = AC1 * BC2 * CC2 * DC1
Total ways = Total ways of case1 + Total ways of case2 + Total ways of case3 + Total ways of case 3 + Total ways of case4
instead of dividing factorials we multiply their modular multiplicative inverses.
Follow the steps below to solve the problem:
- Initializing fact[] array and Precomputing all factorials from 1 to 100000.
- initializing ANS variable.
- Calculating the answer by using the above formula.
- Print the answer.
Below is the implementation of the above approach:
C++
// C++ code to implement the approach #include <bits/stdc++.h> using namespace std; // to avoid integer overflow #define int long long const int MOD = 1e9 + 7; // To find GCD of a and b int gcd( int a, int b); // To compute x raised to power y under // modulo M int power( int x, unsigned int y, unsigned int M); // Function to find modular inverse of // under modulo M // Assumption: M is prime int modInverse( int A, int M) { int g = gcd(A, M); return power(A, M - 2, M); } // To compute x^y under modulo m int power( int x, unsigned int y, unsigned int M) { if (y == 0) return 1; int p = power(x, y / 2, M) % M; p = (p * p) % M; return (y % 2 == 0) ? p : (x * p) % M; } // Function to return gcd of a and b int gcd( int a, int b) { if (a == 0) return b; return gcd(b % a, a); } // Function to Count number of ways // of taking 3 red balls and 3 blue // balls so that 3 balls are from box1 // and 3 balls are from box 2 int countWays( int A, int B, int C, int D) { // Precomputation array storing // factorials MOD 1e9 + 7 int fact[100001]; // Initialize the base elements fact[1] = 1, fact[0] = 1; // Filling factorial table for ( int i = 2; i <= 100000; i++) { fact[i] = (fact[i - 1] * i) % MOD; } // case 1 multiplying A!/(A-2)! int ans1 = (fact[A] * modInverse(fact[A - 2], MOD)) % MOD; // case 1 multiplying B!/(B-1)! ans1 = (ans1 * fact[B] * modInverse(fact[B - 1], MOD)) % MOD; // case 1 taking into account C!/(C-1)! ans1 = (ans1 * fact[C] * modInverse(fact[C - 1], MOD)) % MOD; // case 1 taking into account D!/(D-1)! ans1 = (ans1 * fact[D] * modInverse(fact[D - 2], MOD)) % MOD; // case 1 taking into account / 4 ans1 = (ans1 * modInverse(4, MOD)) % MOD; // case 2 multiplying A!/(A-3)! int ans2 = (fact[A] * modInverse(fact[A - 3], MOD)) % MOD; // case 2 multiplying D!/(D-3)! ans2 = (ans2 * fact[D] * modInverse(fact[D - 3], MOD)) % MOD; // case 2 taking into account / 36 ans2 = (ans2 * modInverse(36, MOD)) % MOD; // case 3 multiplying B!/(B-3)! int ans3 = (fact[B] * modInverse(fact[B - 3], MOD)) % MOD; // case 3 multiplying C!/(C-3)! ans3 = (ans3 * fact[C] * modInverse(fact[C - 3], MOD)) % MOD; // case 3 taking into account / 36 ans3 = (ans3 * modInverse(36, MOD)) % MOD; // case 4 multiplying A!/(A-1)! int ans4 = (fact[A] * modInverse(fact[A - 1], MOD)) % MOD; // case 4 multiplying B!/(B-2)! ans4 = (ans4 * fact[B] * modInverse(fact[B - 2], MOD)) % MOD; // case 4 taking into account C!/(C-2)! ans4 = (ans4 * fact[C] * modInverse(fact[C - 2], MOD)) % MOD; // case 4 taking into account D!/(D-1)! ans4 = (ans4 * fact[D] * modInverse(fact[D - 1], MOD)) % MOD; // case 4 taking into accont / 4 ans4 = (ans4 * modInverse(4, MOD)) % MOD; // answer int ans = (ans1 + ans2 + ans3 + ans4) % MOD; // Returning the answer return ans; } // Driver Code int32_t main() { // Input 1 int A = 4, B = 3, C = 3, D = 4; // Function Call cout << countWays(A, B, C, D) << endl; // Input 2 int A1 = 3, B1 = 3, C1 = 3, D1 = 3; // Function Call cout << countWays(A1, B1, C1, D1) << endl; return 0; } |
Java
// Java code for the above approach import java.io.*; class GFG { static final int MOD = ( int )1e9 + 7 ; // To find GCD of a and b static int gcd( int a, int b) { if (a == 0 ) return b; return gcd(b % a, a); } // To compute x raised to power y under modulo M static int power( int x, int y, int M) { if (y == 0 ) return 1 ; int p = power(x, y / 2 , M) % M; p = ( int )(( long )p * p % M); return (y % 2 == 0 ) ? p : ( int )(( long )x * p % M); } // Function to find modular inverse of A under modulo M // Assumption: M is prime static int modInverse( int A, int M) { int g = gcd(A, M); return power(A, M - 2 , M); } // Function to Count number of ways // of taking 3 red balls and 3 blue // balls so that 3 balls are from box1 // and 3 balls are from box 2 static int countWays( int A, int B, int C, int D) { // Precomputation array storing factorials MOD 1e9 + // 7 int [] fact = new int [ 100001 ]; // Initialize the base elements fact[ 1 ] = 1 ; fact[ 0 ] = 1 ; // Fill factorial table for ( int i = 2 ; i <= 100000 ; i++) { fact[i] = ( int )(( long )fact[i - 1 ] * i % MOD); } // case 1 multiplying A!/(A-2)! int ans1 = ( int )(( long )fact[A] * modInverse(fact[A - 2 ], MOD) % MOD); // case 1 multiplying B!/(B-1)! ans1 = ( int )(( long )ans1 * fact[B] % MOD * modInverse(fact[B - 1 ], MOD) % MOD); // case 1 taking into account C!/(C-1)! ans1 = ( int )(( long )ans1 * fact[C] % MOD * modInverse(fact[C - 1 ], MOD) % MOD); // case 1 taking into account D!/(D-1)! ans1 = ( int )(( long )ans1 * fact[D] % MOD * modInverse(fact[D - 2 ], MOD) % MOD); // case 1 taking into account / 4 ans1 = ( int )(( long )ans1 * modInverse( 4 , MOD) % MOD); // case 2 multiplying A!/(A-3)! int ans2 = ( int )(( long )fact[A] * modInverse(fact[A - 3 ], MOD) % MOD); // case 2 multiplying D!/(D-3)! ans2 = ( int )(( long )ans2 * fact[D] % MOD * modInverse(fact[D - 3 ], MOD) % MOD); // case 2 taking into account / 36 ans2 = ( int )(( long )ans2 * modInverse( 36 , MOD) % MOD); // case 3 multiplying B!/(B-3)! int ans3 = ( int )(( long )fact[B] * modInverse(fact[B - 3 ], MOD) % MOD); // case 3 multiplying C!/(C-3)! ans3 = ( int )(( long )ans3 * fact[C] % MOD * modInverse(fact[C - 3 ], MOD) % MOD); // case 3 taking into account / 36 ans3 = ( int )(( long )ans3 * modInverse( 36 , MOD) % MOD); // case 4 multiplying A!/(A-1)! int ans4 = ( int )(( long )fact[A] * modInverse(fact[A - 1 ], MOD) % MOD); // case 4 multiplying B!/(B-2)! ans4 = ( int )(( long )ans4 * fact[B] % MOD * modInverse(fact[B - 2 ], MOD) % MOD); // case 4 taking into account C!/(C-2)! ans4 = ( int )(( long )ans4 * fact[C] % MOD * modInverse(fact[C - 2 ], MOD) % MOD); // case 4 taking into account D!/(D-2)! ans4 = ( int )(( long )ans4 * fact[D] % MOD * modInverse(fact[D - 1 ], MOD) % MOD); // case 4 taking into account / 12 ans4 = ( int )(( long )ans4 * modInverse( 4 , MOD) % MOD); return (ans1 + ans2 + ans3 + ans4) % MOD; } public static void main(String[] args) { // Input 1 int A = 4 , B = 3 , C = 3 , D = 4 ; // Function Call System.out.println(countWays(A, B, C, D)); // Input 2 int A1 = 3 , B1 = 3 , C1 = 3 , D1 = 3 ; // Function Call System.out.println(countWays(A1, B1, C1, D1)); } } // This code is contributed by lokesh. |
Python3
# Python code for the above approach import math MOD = int ( 1e9 + 7 ) # To find GCD of a and b def gcd(a: int , b: int ) - > int : if a = = 0 : return b return gcd(b % a, a) # To compute x raised to power y under # modulo M def power(x: int , y: int , M: int ) - > int : if y = = 0 : return 1 p = power(x, y / / 2 , M) % M p = (p * p) % M return (p if y % 2 = = 0 else (x * p) % M) # Function to find modular inverse of # under modulo M # Assumption: M is prime def modInverse(A: int , M: int ) - > int : g = gcd(A, M) return power(A, M - 2 , M) # Function to Count number of ways # of taking 3 red balls and 3 blue # balls so that 3 balls are from box1 # and 3 balls are from box 2 def countWays(A: int , B: int , C: int , D: int ) - > int : # Precomputation array storing # factorials MOD 1e9 + 7 fact = [ 1 for i in range ( 100001 )] # Filling factorial table for i in range ( 2 , 100001 ): fact[i] = (fact[i - 1 ] * i) % MOD # case 1 multiplying A!/(A-2)! ans1 = (fact[A] * modInverse(fact[A - 2 ], MOD)) % MOD # case 1 multiplying B!/(B-1)! ans1 = (ans1 * fact[B] * modInverse(fact[B - 1 ], MOD)) % MOD # case 1 taking into account C!/(C-1)! ans1 = (ans1 * fact[C] * modInverse(fact[C - 1 ], MOD)) % MOD # case 1 taking into account D!/(D-1)! ans1 = (ans1 * fact[D] * modInverse(fact[D - 2 ], MOD)) % MOD # case 1 taking into account / 4 ans1 = (ans1 * modInverse( 4 , MOD)) % MOD # case 2 multiplying A!/(A-3)! ans2 = (fact[A] * modInverse(fact[A - 3 ], MOD)) % MOD # case 2 multiplying D!/(D-3)! ans2 = (ans2 * fact[D] * modInverse(fact[D - 3 ], MOD)) % MOD # case 2 taking into account / 36 ans2 = (ans2 * modInverse( 36 , MOD)) % MOD # case 3 multiplying B!/(B-3)! ans3 = (fact[B] * modInverse(fact[B - 3 ], MOD)) % MOD # case 3 multiplying C!/(C-3)! ans3 = (ans3 * fact[C] * modInverse(fact[C - 3 ], MOD)) % MOD # case 3 taking into account / 36 ans3 = (ans3 * modInverse( 36 , MOD)) % MOD # case 4 multiplying A!/(A-1)! ans4 = (fact[A] * modInverse(fact[A - 1 ], MOD)) % MOD # case 4 multiplying B!/(B-2)! ans4 = (ans4 * fact[B] * modInverse(fact[B - 2 ], MOD)) % MOD # case 4 taking into account C!/(C-2)! ans4 = (ans4 * fact[C] * modInverse(fact[C - 2 ], MOD)) % MOD # case 4 taking into account D!/(D-2)! ans4 = (ans4 * fact[D] * modInverse(fact[D - 1 ], MOD)) % MOD # case 4 taking into account / 12 ans4 = (ans4 * modInverse( 4 , MOD)) % MOD # Return the final answer return (ans1 + ans2 + ans3 + ans4) % MOD # Driver code if __name__ = = '__main__' : A = 4 # Number of red balls in box 1 B = 3 # Number of blue balls in box 1 C = 3 # Number of red balls in box 2 D = 4 # Number of blue balls in box 2 # Function call to find number of ways print ( int (countWays(A, B, C, D))) A = 3 # Number of red balls in box 1 B = 3 # Number of blue balls in box 1 C = 3 # Number of red balls in box 2 D = 3 # Number of blue balls in box 2 # Function call to find number of ways print ( int (countWays(A, B, C, D))) # This code is contributed by Potta Lokesh |
C#
// C# code to implement the approach using System; using System.Collections.Generic; class GFG { const long MOD = 1000000007; // Function to return gcd of a and b static long gcd( long a, long b) { if (a == 0) return b; return gcd(b % a, a); } // To compute x^y under modulo m static long power( long x, long y, long M) { if (y == 0) return 1; long p = power(x, y / 2, M) % M; p = (p * p) % M; return (y % 2 == 0) ? p : (x * p) % M; } // Function to find modular inverse of // under modulo M // Assumption: M is prime static long modInverse( long A, long M) { long g = gcd(A, M); return power(A, M - 2, M); } // Function to Count number of ways // of taking 3 red balls and 3 blue // balls so that 3 balls are from box1 // and 3 balls are from box 2 static long countWays( long A, long B, long C, long D) { // Precomputation array storing // factorials MOD 1e9 + 7 long [] fact= new long [100001]; // Initialize the base elements fact[1] = 1; fact[0] = 1; // Filling factorial table for ( long i = 2; i <= 100000; i++) { fact[i] = (fact[i - 1] * i) % MOD; } // case 1 multiplying A!/(A-2)! long ans1 = (fact[A] * modInverse(fact[A - 2], MOD)) % MOD; // case 1 multiplying B!/(B-1)! ans1 = (ans1 * fact[B] * modInverse(fact[B - 1], MOD)) % MOD; // case 1 taking longo account C!/(C-1)! ans1 = (ans1 * fact[C] * modInverse(fact[C - 1], MOD)) % MOD; // case 1 taking longo account D!/(D-1)! ans1 = (ans1 * fact[D] * modInverse(fact[D - 2], MOD)) % MOD; // case 1 taking longo account / 4 ans1 = (ans1 * modInverse(4, MOD)) % MOD; // case 2 multiplying A!/(A-3)! long ans2 = (fact[A] * modInverse(fact[A - 3], MOD)) % MOD; // case 2 multiplying D!/(D-3)! ans2 = (ans2 * fact[D] * modInverse(fact[D - 3], MOD)) % MOD; // case 2 taking longo account / 36 ans2 = (ans2 * modInverse(36, MOD)) % MOD; // case 3 multiplying B!/(B-3)! long ans3 = (fact[B] * modInverse(fact[B - 3], MOD)) % MOD; // case 3 multiplying C!/(C-3)! ans3 = (ans3 * fact[C] * modInverse(fact[C - 3], MOD)) % MOD; // case 3 taking longo account / 36 ans3 = (ans3 * modInverse(36, MOD)) % MOD; // case 4 multiplying A!/(A-1)! long ans4 = (fact[A] * modInverse(fact[A - 1], MOD)) % MOD; // case 4 multiplying B!/(B-2)! ans4 = (ans4 * fact[B] * modInverse(fact[B - 2], MOD)) % MOD; // case 4 taking longo account C!/(C-2)! ans4 = (ans4 * fact[C] * modInverse(fact[C - 2], MOD)) % MOD; // case 4 taking longo account D!/(D-1)! ans4 = (ans4 * fact[D] * modInverse(fact[D - 1], MOD)) % MOD; // case 4 taking longo accont / 4 ans4 = (ans4 * modInverse(4, MOD)) % MOD; // answer long ans = (ans1 + ans2 + ans3 + ans4) % MOD; // Returning the answer return ans; } // Driver Code public static void Main() { // Input 1 long A = 4, B = 3, C = 3, D = 4; // Function Call Console.Write(countWays(A, B, C, D)+ "\n" ); // Input 2 long A1 = 3, B1 = 3, C1 = 3, D1 = 3; // Function Call Console.Write(countWays(A1, B1, C1, D1)+ "\n" ); } } // This code is contributed by agrawalpoojaa976. |
Javascript
// Javascript code for the above approach const MOD = BigInt(1e9 + 7); // To find GCD of a and b function gcd(a, b) { if (a == 0n) { return b; } return gcd(b % a, a); } // To compute x raised to power y under // modulo M function power(x, y, M) { if (y == 0n) { return 1n; } let p = power(x, y / 2n, M) % M; p = (p * p) % M; return (y % 2n == 0n ? p : (x * p) % M); } // Function to find modular inverse of // under modulo M // Assumption: M is prime function modInverse(A, M) { const g = gcd(A, M); return power(A, M - 2n, M); } // Function to Count number of ways // of taking 3 red balls and 3 blue // balls so that 3 balls are from box1 // and 3 balls are from box 2 function countWays(A, B, C, D) { // Precomputation array storing // factorials MOD 1e9 + 7 const fact = [BigInt(1)]; // Filling factorial table for (let i = 1n; i <= 100000n; i++) { fact.push((fact[i - 1n] * i) % MOD); } // case 1 multiplying A!/(A-2)! let ans1 = (fact[A] * modInverse(fact[A - 2n], MOD)) % MOD; // case 1 multiplying B!/(B-1)! ans1 = (ans1 * fact[B] * modInverse(fact[B - 1n], MOD)) % MOD; // case 1 taking into account C!/(C-1)! ans1 = (ans1 * fact[C] * modInverse(fact[C - 1n], MOD)) % MOD; // case 1 taking into account D!/(D-1)! ans1 = (ans1 * fact[D] * modInverse(fact[D - 2n], MOD)) % MOD; // case 1 taking into account / 4 ans1 = (ans1 * modInverse(4n, MOD)) % MOD; // case 2 multiplying A!/(A-3)! let ans2 = (fact[A] * modInverse(fact[A - 3n], MOD)) % MOD; // case 2 multiplying D!/(D-3)! ans2 = (ans2 * fact[D] * modInverse(fact[D - 3n], MOD)) % MOD; // case 2 taking into account / 36 ans2 = (ans2 * modInverse(36n, MOD)) % MOD; // case 3 multiplying B!/(B-3)! let ans3 = (fact[B] * modInverse(fact[B - 3n], MOD)) % MOD; // case 3 multiplying C!/(C-3)! ans3 = (ans3 * fact[C] * modInverse(fact[C - 3n], MOD)) % MOD; // case 3 taking into account / 36 ans3 = (ans3 * modInverse(36n, MOD)) % MOD; // case 4 multiplying A!/(A-1)! let ans4 = (fact[A] * modInverse(fact[A - 1n], MOD)) % MOD; // case 4 multiplying B!/(B-2)! ans4 = (ans4 * fact[B] * modInverse(fact[B - 2n], MOD)) % MOD; // case 4 taking into account C!/(C-2)! ans4 = (ans4 * fact[C] * modInverse(fact[C - 2n], MOD)) % MOD; // case 4 taking into account D!/(D-2)! ans4 = (ans4 * fact[D] * modInverse(fact[D - 1n], MOD)) % MOD; // case 4 taking into account / 12 ans4 = (ans4 * modInverse(4n, MOD)) % MOD; // Return the final answer return Number((ans1 + ans2 + ans3 + ans4) % MOD); } // Driver Code console.log(countWays(4n, 3n, 3n, 4n)); console.log(countWays(3n, 3n, 3n, 3n)); // This code is contributed by sdeadityasharma |
485 164
Time Complexity: O(N)
Auxiliary Space: O(N)
Related Articles:
Please Login to comment...