Probability of getting more heads than tails when N biased coins are tossed

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



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

  1. If number of heads till (i – 1) coins is equal to j then a tail comes at ith.
  2. 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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 there is only one possiblity
            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 permuation 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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the above approach
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 there is only one possiblity
            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 permuation 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

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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 there is only one possiblity 
            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 permuation 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 there is only one possiblity
            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 permuation 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.

chevron_right


Output:

0.442


My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : Rajput-Ji, jit_t, AnkitRai01