📌  相关文章
📜  投掷N个有偏见的硬币时,正面比背面多的可能性

📅  最后修改于: 2021-05-06 08:48:09             🧑  作者: Mango

给定一个奇数长度为N的数组p [] ,其中p [i]表示在第i硬币上出现正面的概率。由于硬币有偏差,因此获得正面的可能性并不总是等于0.5 。任务是找到使头的次数多于头的机会。

例子:

天真的方法:天真的方法将创建正面和反面的所有2 n种可能性。然后计算不同排列的概率,并在头数大于尾数时将其相加,如示例说明所示。当n大时,这将给TLE。

高效的方法:这个想法是使用动态编程。假设dp [i] [j]是前i个硬币获得j个头的概率。为了使j个头位于第i位置,有两种可能性:

  1. 如果直到(i – 1)个硬币的正面数目等于j,i背面出现尾数
  2. 如果直到(i – 1)个硬币的正面数等于(j – 1),则正面在i位置

因此,它可以分为以下子问题:

下面是上述方法的实现:

C++
// C++ implementation of the above approach
#include 
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;
}


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


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


C#
// 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.


输出:
0.442