给定一个奇数长度为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 个正面的概率。要在第i个位置获得j个正面,有两种可能性:
- 如果直到(i – 1) 个硬币的正面数量等于j,则尾部出现在i th 处。
- 如果直到(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 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
// 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 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
# 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 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#
// 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 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.
Javascript
0.442
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。