Given an array p[] of odd length N where p[i] denotes the probability of getting a head on the ith coin. As the coins are biased, the probability of getting a head is not always equal to 0.5. The task is to find the probability of getting heads more number of times than tails.
Examples:
Input: p[] = {0.3, 0.4, 0.7}
Output: 0.442
Probability for a tail = (1 – Probability for a head)
For heads greater than tails, there are 4 possibilities:
P({head, head, tail}) = 0.3 x 0.4 x (1 – 0.7) = 0.036
P({tail, head, head}) = (1 – 0.3) x 0.4 x 0.7 = 0.196
P({head, tail, head}) = 0.3 x (1 – 0.4) x 0.7= 0.126
P({head, head, head}) = 0.3 x 0.4 x 0.7 = 0.084
Adding the above probabilities
0.036 + 0.196 + 0.126 + 0.084 = 0.442Input: p[] = {0.3, 0.5, 0.2, 0.6, 0.9}
Output: 0.495
Naive approach: The naive approach would be creating all the 2n possibilities of heads and tails. Then calculating the probabilities for different permutations and adding them when the number of heads are greater than the number of tails just like the example explanation. This would give TLE when n is large.
Efficient approach: The idea is to use dynamic programming. Let’s assume dp[i][j] to be the probability of getting j heads with first i coins. To get j heads at the ith position, there are two possibilities:
- If number of heads till (i – 1) coins is equal to j then a tail comes at ith.
- If number of heads till (i – 1) coins is equal to (j – 1) then a head comes at ith position
Hence, it can be broken into its subproblems as follows:
dp[i][j] = dp[i – 1][j] * (1 – p[i]) + dp[i – 1][j – 1] * p[i]
Below is the implementation of the above approach:
// C++ implementation of the above approach #include <bits/stdc++.h> using namespace std;
// Function to return the probability when // number of heads is greater than the number of tails double Probability( double p[], int n)
{ // Declaring the DP table
double dp[n + 1][n + 1];
memset (dp, 0.0, sizeof (dp));
// Base case
dp[0][0] = 1.0;
// Iterating for every coin
for ( int i = 1; i <= n; i += 1) {
// j represents the numbers of heads
for ( int j = 0; j <= i; j += 1) {
// If number of heads is equal to zero
// there is only one possibility
if (j == 0)
dp[i][j] = dp[i - 1][j]
* (1.0 - p[i]);
else
dp[i][j] = dp[i - 1][j]
* (1.0 - p[i])
+ dp[i - 1][j - 1] * p[i];
}
}
double ans = 0.0;
// When the number of heads is greater than (n+1)/2
// it means that heads are greater than tails as
// no of tails + no of heads is equal to n for
// any permutation of heads and tails
for ( int i = (n + 1) / 2; i <= n; i += 1)
ans += dp[n][i];
return ans;
} // Driver Code int main()
{ // 1 based indexing
double p[] = { 0.0, 0.3, 0.4, 0.7 };
// Number of coins
int n = sizeof (p) / sizeof (p[0]) - 1;
// Function call
cout << Probability(p, n);
return 0;
} |
// Java implementation of the above approach import java.io.*;
class GFG
{ // Function to return the probability when // number of heads is greater than the number of tails static double Probability( double p[], int n)
{ // Declaring the DP table
double [][]dp = new double [n + 1 ][n + 1 ];
// Base case
dp[ 0 ][ 0 ] = 1.0 ;
// Iterating for every coin
for ( int i = 1 ; i <= n; i += 1 )
{
// j represents the numbers of heads
for ( int j = 0 ; j <= i; j += 1 )
{
// If number of heads is equal to zero
// there is only one possibility
if (j == 0 )
dp[i][j] = dp[i - 1 ][j]
* ( 1.0 - p[i]);
else
dp[i][j] = dp[i - 1 ][j]
* ( 1.0 - p[i])
+ dp[i - 1 ][j - 1 ] * p[i];
}
}
double ans = 0.0 ;
// When the number of heads is greater than (n+1)/2
// it means that heads are greater than tails as
// no of tails + no of heads is equal to n for
// any permutation of heads and tails
for ( int i = (n + 1 ) / 2 ; i <= n; i += 1 )
ans += dp[n][i];
return ans;
} // Driver Code public static void main(String[] args)
{ // 1 based indexing
double p[] = { 0.0 , 0.3 , 0.4 , 0.7 };
// Number of coins
int n = p.length - 1 ;
// Function call
System.out.println(Probability(p, n));
} } // This code is contributed by Rajput-Ji |
# Python3 implementation of the above approach import numpy as np
# Function to return the probability when # number of heads is greater than # the number of tails def Probability(p, n) :
# Declaring the DP table
dp = np.zeros((n + 1 , n + 1 ));
for i in range (n + 1 ) :
for j in range (n + 1 ) :
dp[i][j] = 0.0
# Base case
dp[ 0 ][ 0 ] = 1.0 ;
# Iterating for every coin
for i in range ( 1 , n + 1 ) :
# j represents the numbers of heads
for j in range (i + 1 ) :
# If number of heads is equal to zero
# there is only one possibility
if (j = = 0 ) :
dp[i][j] = dp[i - 1 ][j] * ( 1.0 - p[i]);
else :
dp[i][j] = (dp[i - 1 ][j] * ( 1.0 - p[i]) +
dp[i - 1 ][j - 1 ] * p[i]);
ans = 0.0 ;
# When the number of heads is greater than (n+1)/2
# it means that heads are greater than tails as
# no of tails + no of heads is equal to n for
# any permutation of heads and tails
for i in range ((n + 1 ) / / 2 , n + 1 ) :
ans + = dp[n][i];
return ans;
# Driver Code if __name__ = = "__main__" :
# 1 based indexing
p = [ 0.0 , 0.3 , 0.4 , 0.7 ];
# Number of coins
n = len (p) - 1 ;
# Function call
print (Probability(p, n));
# This code is contributed by AnkitRai01 |
// C# implementation of the above approach using System;
class GFG
{ // Function to return the probability when // number of heads is greater than the number of tails static double Probability( double []p, int n)
{ // Declaring the DP table
double [,]dp = new double [n + 1, n + 1];
// Base case
dp[0, 0] = 1.0;
// Iterating for every coin
for ( int i = 1; i <= n; i += 1)
{
// j represents the numbers of heads
for ( int j = 0; j <= i; j += 1)
{
// If number of heads is equal to zero
// there is only one possibility
if (j == 0)
dp[i,j] = dp[i - 1,j]
* (1.0 - p[i]);
else
dp[i,j] = dp[i - 1,j]
* (1.0 - p[i])
+ dp[i - 1,j - 1] * p[i];
}
}
double ans = 0.0;
// When the number of heads is greater than (n+1)/2
// it means that heads are greater than tails as
// no of tails + no of heads is equal to n for
// any permutation of heads and tails
for ( int i = (n + 1) / 2; i <= n; i += 1)
ans += dp[n,i];
return ans;
} // Driver Code static public void Main ()
{ // 1 based indexing
double []p = { 0.0, 0.3, 0.4, 0.7 };
// Number of coins
int n = p.Length - 1;
// Function call
Console.Write(Probability(p, n));
} } // This code is contributed by ajit. |
<script> // Javascript implementation of the above approach // Function to return the probability when // number of heads is greater than the number of tails function Probability(p , n)
{ // Declaring the DP table
var dp = Array(n + 1).fill(0).map(
x => Array(n + 1).fill(0));
// Base case
dp[0][0] = 1.0;
// Iterating for every coin
for ( var i = 1; i <= n; i += 1)
{
// j represents the numbers of heads
for ( var j = 0; j <= i; j += 1)
{
// If number of heads is equal to zero
// there is only one possibility
if (j == 0)
dp[i][j] = dp[i - 1][j] *
(1.0 - p[i]);
else
dp[i][j] = dp[i - 1][j] * (1.0 - p[i]) +
dp[i - 1][j - 1] * p[i];
}
}
var ans = 0.0;
// When the number of heads is greater than (n+1)/2
// it means that heads are greater than tails as
// no of tails + no of heads is equal to n for
// any permutation of heads and tails
for ( var i = parseInt((n + 1) / 2); i <= n; i += 1)
ans += dp[n][i];
return ans;
} // Driver Code // 1 based indexing var p = [ 0.0, 0.3, 0.4, 0.7 ];
// Number of coins var n = p.length - 1;
// Function call document.write(Probability(p, n)); // This code is contributed by Amit Katiyar </script> |
0.442
Time complexity: O(n2), where n is the size of the given array.
Auxiliary space: O(n2) because using extra space for array dp