题意:n个人排成一队按队伍序列上扶梯,共 t 时刻,每时刻最多进一个人,进的概率为p,已经进去的人不能再出来,若排在队首的不进则后边的人无法进,求 t 时刻后扶梯上人数的数学期望。
一维表示时刻,二维表示人数,有状态转移方程
dp[ i + 1 ] [ j + 1 ] = dp[ i ] [ j ] * p; //这一时刻进了一个人
dp[ i + 1 ] [ j ] = dp[ i ] [ j ] * (1.0 - p); //这一时刻未进人
赋初值时,0时刻必为0个人,dp[0][0] = 1.0;
统计结果时,
对于0 <= i < n 的部分,即为 dp[ t ] [ i ] * i;
对于n <= i <= t 的部分,即为dp[ i ] [ n ] * n;
#include<cstdio>
#include<cstring>
#include<cctype>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<sstream>
#include<iterator>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<list>
typedef long long ll;
typedef unsigned long long llu;
const int MAXN = 2000 + 10;
const int MAXT = 10000 + 10;
const int INF = 0x7f7f7f7f;
const double pi = acos(-1.0);
const double EPS = 1e-6;
using namespace std;
int n, t;
double p, ans, dp[MAXN][MAXN];
int main(){
ans = 0.0;
scanf("%d%lf%d", &n, &p, &t);
memset(dp, 0, sizeof dp);
dp[0][0] = 1.0;
for(int i = 0; i <= t; ++i){
for(int j = 0; j < n; ++j){
dp[i + 1][j + 1] += dp[i][j] * p;
dp[i + 1][j] += dp[i][j] * (1.0 - p);
}
}
for(int i = 0; i < n; ++i) ans += dp[t][i] * (double)i;
for(int i = n; i <= t; ++i) ans += dp[i][n] * (double)n;
printf("%.8lf\n", ans);
return 0;
}