题目大意
有
n
n
n个人,排成一列,现在他们将要进入自动扶梯。
已知在
1
1
1秒内,排在对头的人有
p
p
p的概率进入自动扶梯,有
1
−
p
1-p
1−p的概率保持不动。
n
n
n个人必须依次进入自动扶梯,进入了自动扶梯的人不会再次离开扶梯。
问在
t
t
t秒后,自动扶梯里人数的期望是多少。
时间限制
2s
数据范围
n , t ≤ 2000 n,t\le2000 n,t≤2000
题解
一个非常好想到的dp,
设
f
i
,
j
f_{i,j}
fi,j表示在第
i
i
i秒,自动扶梯里有
j
j
j个人的概率。
转移显然
f
i
,
j
=
f
i
−
1
,
j
×
(
1
−
p
)
+
f
i
−
1
,
j
−
1
×
p
f_{i,j}=f{i-1,j}\times\pod{1-p}+f_{i-1,j - 1}\times p
fi,j=fi−1,j×(1−p)+fi−1,j−1×p
值得注意的是,
f
i
,
n
=
f
i
−
1
,
n
+
f
i
−
1
,
n
−
1
×
p
f_{i,n}=f{i-1,n}+f_{i-1,n-1}\times p
fi,n=fi−1,n+fi−1,n−1×p,因为当
n
n
n个人已经全部进入自动扶梯之后,整个过程就结束了,不再需要接着计算概率。
Code
//#pragma GCC optimize (2)
//#pragma G++ optimize (2)
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <vector>
#include <queue>
#define G getchar
#define ll long long
using namespace std;
ll read()
{
char ch;
for(ch = G();(ch < '0' || ch > '9') && ch != '-';ch = G());
ll n = 0 , w;
if (ch == '-')
{
w = -1;
ch = G();
} else w = 1;
for(;'0' <= ch && ch <= '9';ch = G())n = (n<<1)+(n<<3)+ch-48;
return n * w;
}
const int N = 2003;
const int mo = 998244353;
int n , k;
double p , p0 , f[N][N] , ans;
int main()
{
//freopen("b.in","r",stdin);
//freopen("2.txt","w",stdout);
n = read();
scanf("%lf", &p);
p0 = 1 - p;
k = read();
f[0][0] = 1;
for (int i = 1 ; i <= k ; i++)
{
f[i][0] = f[i - 1][0] * p0;
for (int j = 1 ; j < n ; j++)
f[i][j] = f[i - 1][j] * p0 + f[i - 1][j - 1] * p;
f[i][n] = f[i - 1][n] + f[i - 1][n - 1] * p;
}
for (int i = 1 ; i <= n ; i++)
ans = ans + f[k][i] * i;
printf("%.8lf\n", ans);
}