【题目描述】

有 $N$ 个人排成一队,每秒,队首的人有 $p$ 的概率走上电梯(此后就一直待在上面),或有 $1 - p$ 的概率不动,求 $T$ 秒过后,电梯上的人数的期望。

【题目链接】

CF 518D Ilya and Escalator

【解题思路】

我们直接考虑期望的定义:随机变量 $x$ 的期望 $E[x]$ 是 $x$ 所有取值按概率加权的和。

在本题中,如果设 $f[i][j]$ 表示 $i$ 秒后电梯上有 $j$ 个人的概率,那么答案即为: $$ ans = \sum_{1 \leq j \leq N} f[T][j] \times j $$

如何求 $f[i][j]$ 呢?

当 $j \lt N$ 时,考虑第一个人上或不上电梯,容易得到:

$$ f[i + 1][j + 1] \leftarrow f[i][j] \times p $$

$$ f[i + 1][j] \leftarrow f[i][j] \times (1 - p) $$

当 $j = N$ 时,所有的人都在电梯上了,下一秒必然也是如此: $$ f[i + 1][N] \leftarrow f[i][N] $$

总结:考虑期望的定义,将其转化成求概率的问题。

【AC代码】

第一次在 CF 上做题。

#include <iostream>
#include <iomanip>

const int MAXT = 2000;
const int MAXN = 2000;

int n, t;
double p;

double f[MAXT + 1][MAXN + 1];

inline double solve(){
    f[0][0] = 1;
    for(int i = 0; i < t; i++){
        for(int j = 0; j < n; j++){
            f[i + 1][j + 1] += f[i][j] * p;
            f[i + 1][j] += f[i][j] * (1 - p);
        }

        f[i + 1][n] += f[i][n];
    }

    double ans = 0;
    for(int i = 0; i <= n; i++) ans += i * f[t][i];

    return ans;
}

int main(){
    std::cin >> n >> p >> t;

    std::cout.setf(std::ios::fixed);
    std::cout << std::setprecision(6) << solve() << std::endl;

    return 0;
}

就是这样啦~