给定一个奇数长度为N的数组p [] ,其中p [i]表示在第i个硬币上出现正面的概率。由于硬币有偏差,因此获得正面的可能性并不总是等于0.5 。任务是找到使头的次数多于头的机会。
例子:
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
天真的方法:天真的方法将创建正面和反面的所有2 n种可能性。然后计算不同排列的概率,并在头数大于尾数时将其相加,如示例说明所示。当n大时,这将给TLE。
高效的方法:这个想法是使用动态编程。假设dp [i] [j]是前i个硬币获得j个头的概率。为了使j个头位于第i个位置,有两种可能性:
- 如果直到(i – 1)个硬币的正面数目等于j,则第i个背面出现尾数。
- 如果直到(i – 1)个硬币的正面数等于(j – 1),则正面在第i个位置
因此,它可以分为以下子问题:
dp[i][j] = dp[i – 1][j] * (1 – p[i]) + dp[i – 1][j – 1] * p[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