📜  获得 n 个连续正面的预期试验次数 - C++ (1)

📅  最后修改于: 2023-12-03 15:11:53.590000             🧑  作者: Mango

题目描述

给定一个硬币,正面向上的概率为 $p$,反面向上的概率为 $1-p$,现在进行一些试验,直到获得了 $n$ 个连续正面。求期望需要进行的试验次数。

算法思路

设 $f_i$ 表示当前已经获得了 $i$ 个连续正面,需要进行的期望试验次数。

当 $i<n$ 时,显然需要继续进行试验,因此 $f_i=1+pf_{i+1}+(1-p)f_0$。

当 $i\geq n$ 时,如果硬币朝上,那么已经获得了连续的 $n$ 个正面,可以停止试验;如果硬币朝下,那么需要重新开始试验。因此 $f_i=1+pf_{i+1}+(1-p)f_{i-n}$。

故有 $f_0=0,\ f_i=1+pf_{i+1}+(1-p)f_{i-n}$。

根据线性递推的方法,先求出 $f_1$ 到 $f_{n-1}$,然后 $f_n$ 就可以根据上述递推式求出来。

代码实现

double getExpectation(int n, double p) {
    vector<double> f(n+1);
    f[0] = 0, f[1] = 1/p;
    for (int i = 2; i < n; ++i) {
        double a = pow(1-p, i), b = pow(p, i);
        f[i] = (1 + p*f[i-1] + (1-p)*f[0]) / (1 - a);
    }
    double a = pow(1-p, n), b = pow(p, n);
    f[n] = (1 + p*f[n-1] + (1-p)*f[n-n]) / (1 - a);
    return f[n];
}

复杂度分析

时间复杂度为 $O(n)$。