原文:

给定 n 个硬币,任务是在同时投掷所有 n 个硬币后,找到获得至少 k 个头像的概率。 例:

suppose we have 3 unbiased coins and we have to
find the probability of getting at least 2 heads,
so there are 23 = 8 ways to toss these
coins, i.e.,
hhh, hht, hth, htt, thh, tht, tth, ttt 
out of which there are 4 set which contain at
least 2 heads i.e.,
hhh, hht, hh, thh
so the probability is 4/8 or 0.5

n 次试验中恰好 k 次成功的概率与任意一次试验中成功的概率 p 由下式给出: 所以概率(得到至少 4 个头)= 方法 1(naive) naive 方法是将阶乘的值存储在 dp[]数组中,并在需要时直接调用。但是这种方法的问题是,我们只能把它存储到一定的值,之后就会导致溢出。 以下是上述方法的实施

c

// naive approach in c   to find probability of
// at least k heads
#include
using namespace std;
#define max 21
double fact[max];
// returns probability of getting at least k
// heads in n tosses.
double probability(int k, int n)
{
    double ans = 0;
    for (int i = k; i <= n;   i)
        // probability of getting exactly i
        // heads out of n heads
        ans  = fact[n] / (fact[i] * fact[n - i]);
    // note: 1 << n = pow(2, n)
    ans = ans / (1ll << n);
    return ans;
}
void precompute()
{
    // preprocess all factorial only upto 19,
    // as after that it will overflow
    fact[0] = fact[1] = 1;
    for (int i = 2; i < 20;   i)
        fact[i] = fact[i - 1] * i;
}
// driver code
int main()
{
    precompute();
    // probability of getting 2 head out of 3 coins
    cout << probability(2, 3) << "\n";
    // probability of getting 3 head out of 6 coins
    cout << probability(3, 6) <<"\n";
    // probability of getting 12 head out of 18 coins
    cout << probability(12, 18);
    return 0;
}

java 语言(一种计算机语言,尤用于创建网站)

// java code for probability of getting
// atleast k heads in n tosses of coins
class gfg {
    public static double fact[];
    // returns probability of getting at least k
    // heads in n tosses.
    public static double probability(int k, int n)
    {
        double ans = 0;
        for (int i = k; i <= n;    i)
            // probability of getting exactly i
            // heads out of n heads
            ans  = fact[n] / (fact[i] * fact[n-i]);
        // note: 1 << n = pow(2, n)
        ans = ans / (1 << n);
        return ans;
    }
    public static void precompute()
    {
        // preprocess all factorial only upto 19,
        // as after that it will overflow
        fact[0] = fact[1] = 1;
        for (int i = 2; i < 20;   i)
            fact[i] = fact[i - 1] * i;
    }
    // driver code
    public static void main(string[] args)
    {
        fact = new double[100];
        precompute();
        // probability of getting 2 head out
        // of 3 coins
        system.out.println(probability(2, 3));
        // probability of getting 3 head out
        // of 6 coins
        system.out.println(probability(3, 6));
        // probability of getting 12 head out
        // of 18 coins
        system.out.println(probability(12, 18));
    }
 }
// this code is contributed by arnav kr. mandal

python 3

# naive approach in python3
# to find probability of
# at least k heads
max=21
fact=[0]*max
# returns probability of
# getting at least k
# heads in n tosses.
def probability(k, n):
    ans = 0
    for i in range(k,n 1):
        # probability of getting exactly i
        # heads out of n heads
        ans  = fact[n] / (fact[i] * fact[n - i])
    # note: 1 << n = pow(2, n)
    ans = ans / (1 << n)
    return ans
def precompute():
    # preprocess all factorial
    # only upto 19,
    # as after that it
    # will overflow
    fact[0] = 1
    fact[1] = 1
    for i in range(2,20):
        fact[i] = fact[i - 1] * i
# driver code
if __name__=='__main__':
    precompute()
    # probability of getting 2
    # head out of 3 coins
    print(probability(2, 3))
    # probability of getting
    # 3 head out of 6 coins
    print(probability(3, 6))
    # probability of getting
    # 12 head out of 18 coins
    print(probability(12, 18))
# this code is contributed by
# mits

c

// c# code for probability of getting
// atleast k heads in n tosses of coins
using system;
class gfg
{
    public static double []fact;
    // returns probability of getting at least k
    // heads in n tosses.
    public static double probability(int k, int n)
    {
        double ans = 0;
        for (int i = k; i <= n;    i)
            // probability of getting exactly i
            // heads out of n heads
            ans  = fact[n] / (fact[i] * fact[n - i]);
        // note: 1 << n = pow(2, n)
        ans = ans / (1 << n);
        return ans;
    }
    public static void precompute()
    {
        // preprocess all factorial only upto 19,
        // as after that it will overflow
        fact[0] = fact[1] = 1;
        for (int i = 2; i < 20;   i)
            fact[i] = fact[i - 1] * i;
    }
    // driver code
    public static void main()
    {
        fact = new double[100];
        precompute();
        // probability of getting 2 head out
        // of 3 coins
        console.writeline(probability(2, 3));
        // probability of getting 3 head out
        // of 6 coins
        console.writeline(probability(3, 6));
        // probability of getting 12 head out
        // of 18 coins
        console.write(probability(12, 18));
    }
}
// this code is contributed by nitin mittal.

服务器端编程语言(professional hypertext preprocessor 的缩写)


java 描述语言


输出:

0.5
0.65625
0.118942

时间复杂度: o(n)其中 n < 20 辅助空间: o(n) 方法二(动态规划和 log) 另一种方式是使用动态规划和对数。log()对于存储任意数字的阶乘而不用担心溢出确实很有用。让我们看看我们如何使用它:

at first let see how n! can be written.
n! = n * (n-1) * (n-2) * (n-3) * ... * 3 * 2 * 1
now take log on base 2 both the sides as:
=> log(n!) = log(n)   log(n-1)   log(n-2)   ...   log(3) 
           log(2)   log(1)
now whenever we need to find the factorial of any number, we can use
this precomputed value. for example:
suppose if we want to find the value of nci which can be written as:
=> nci = n! / (i! * (n-i)! )
taking log2() both sides as:
=> log2 (nci) = log2 ( n! / (i! * (n-i)! ) )
=> log2 (nci) = log2 ( n! ) - log2(i!) - log2( (n-i)! )  `
putting dp[num] = log2 (num!), we get:
=> log2 (nci) = dp[n] - dp[i] - dp[n-i] 
but as we see in above relation there is an extra factor of 2n which
tells the probability of getting i heads, so
=> log2 (2n) = n.
we will subtract this n from above result to get the final answer:
=> pi (log2 (nci)) = dp[n] - dp[i] - dp[n-i] - n
now: pi (nci) = 2 dp[n] - dp[i] - dp[n-i] - n
tada! now the questions boils down the summation of pi for all i in
[k, n] will yield the answer which can be calculated easily without
overflow.

下面是说明这一点的代码:

c

// dynamic and logarithm approach find probability of
// at least k heads
#include
using namespace std;
#define max 100001
// dp[i] is going to store log ( i !) in base 2
double dp[max];
double probability(int k, int n)
{
    double ans = 0; // initialize result
    // iterate from k heads to n heads
    for (int i=k; i <= n;   i)
    {
        double res = dp[n] - dp[i] - dp[n-i] - n;
        ans  = pow(2.0, res);
    }
    return ans;
}
void precompute()
{
    // preprocess all the logarithm value on base 2
    for (int i=2; i < max;   i)
        dp[i] = log2(i)   dp[i-1];
}
// driver code
int main()
{
    precompute();
    // probability of getting 2 head out of 3 coins
    cout << probability(2, 3) << "\n";
    // probability of getting 3 head out of 6 coins
    cout << probability(3, 6) << "\n";
    // probability of getting 500 head out of 10000 coins
    cout << probability(500, 1000);
    return 0;
}

java 语言(一种计算机语言,尤用于创建网站)

// dynamic and logarithm approach find probability of
// at least k heads
import java.math.*;
class gfg {
static int max = 100001;
// dp[i] is going to store log ( i !) in base 2
static double dp[] = new double[max];
static double probability(int k, int n)
{
    double ans = 0.0; // initialize result
    // iterate from k heads to n heads
    for (int i=k; i <= n;   i)
    {
        double res = dp[n] - dp[i] - dp[n-i] - n;
        ans  = math.pow(2.0, res);
    }
    return ans;
}
static void precompute()
{
    // preprocess all the logarithm value on base 2
    for (int i=2; i < max;   i)
        dp[i] = (math.log(i)/math.log(2))   dp[i-1];
}
// driver code
public static void main(string args[])
{
    precompute();
    // probability of getting 2 head out of 3 coins
    system.out.println(probability(2, 3));
    // probability of getting 3 head out of 6 coins
    system.out.println(probability(3, 6));
    // probability of getting 500 head out of 10000 coins
    system.out.println(probability(500, 1000));
}
}

python 3

# dynamic and logarithm approach find probability of
# at least k heads
from math import log2
max=100001
# dp[i] is going to store log ( i !) in base 2
dp=[0]*max
def probability( k, n):
    ans = 0 # initialize result
    # iterate from k heads to n heads
    for i in range(k,n 1):
        res = dp[n] - dp[i] - dp[n-i] - n
        ans = ans   pow(2.0, res)
    return ans
def precompute():
    # preprocess all the logarithm value on base 2
    for i in range(2,max):
        dp[i] = log2(i)   dp[i-1]
# driver code
if __name__=='__main__':
    precompute()
    # probability of getting 2 head out of 3 coins
    print(probability(2, 3))
    # probability of getting 3 head out of 6 coins
    print(probability(3, 6))
    # probability of getting 500 head out of 10000 coins
    print(probability(500, 1000))
#this code is contributed by ash264

c

// dynamic and logarithm approach find probability of
// at least k heads
using system;
class gfg
{
static int max = 100001;
// dp[i] is going to store log ( i !) in base 2
static double[] dp = new double[max];
static double probability(int k, int n)
{
    double ans = 0.0; // initialize result
    // iterate from k heads to n heads
    for (int i = k; i <= n;   i)
    {
        double res = dp[n] - dp[i] - dp[n-i] - n;
        ans  = math.pow(2.0, res);
    }
    return ans;
}
static void precompute()
{
    // preprocess all the logarithm value on base 2
    for (int i = 2; i < max;   i)
        dp[i] = (math.log(i) / math.log(2))   dp[i - 1];
}
// driver code
public static void main()
{
    precompute();
    // probability of getting 2 head out of 3 coins
    console.writeline(probability(2, 3));
    // probability of getting 3 head out of 6 coins
    console.writeline(probability(3, 6));
    // probability of getting 500 head out of 10000 coins
    console.writeline(math.round(probability(500, 1000),6));
}
}
// this code is contributed by mits

服务器端编程语言(professional hypertext preprocessor 的缩写)


java 描述语言


输出:

0.5
0.65625
0.512613

时间复杂度: o(n) 辅助空间: o(n) 这种方式对于 1 到 10 之间的大 n 值都是有利的 6 本文由供稿。如果你喜欢 geeksforgeeks 并想投稿,你也可以使用写一篇文章或者把你的文章邮寄到 contribute@geeksforgeeks.org。看到你的文章出现在极客博客pg电子试玩链接主页上,帮助其他极客。 如果发现有不正确的地方,或者想分享更多关于上述话题的信息,请写评论。