题目链接:http://codeforces.com/problemset/problem/518/D
题目大意:有n个人的队列等待上自动扶梯,每秒最多上一个人,每个人在每秒上扶梯的概率是p,求t秒时扶梯上人数的数学期望。
解题思路:扶梯上人数的数学期望=扶梯上人数的概率*人数。dp [ i ] [ j ]表示第i秒有j个人的概率。第i秒最多有i个人,如果i>=n,第i秒最多有n个人。
对于( i = 2 - t ), dp [ i ] [ j ]=dp [ i -1 ] [ j ]*(1-p)。
对于( j = 1 - n )dp [ i ] [ j ] = dp [ i - 1 ] [ j - 1 ] * p。
对于( i >n ) dp [ i ] [ n ] = dp[ i - 1 ] [ n ] + dp [ i-1 ] [ n-1 ]*p。
利用这几个公式 ,注意初始化和边界条件,详见代码。
代码如下:
#include <cstdio>
#include <cmath>
#include <cstring>
const int maxn=2005;
double dp[maxn][maxn];//第i秒上了j个人的概率
int main()
{
int i,n,t,j;
double p,ans=0.0;
memset(dp,0,sizeof(dp));
scanf("%d%lf%d",&n,&p,&t);
dp[1][0]=1-p; // 初始化第一秒有0个人的概率为(1-p)
dp[1][1]=p; // 初始化第一秒有1个人的概率为 p
for(i=2;i<=t;i++) //初始化j为0的所有情况,如果t>n,最后累加时j只到n,所以这里不做处理
dp[i][0]=dp[i-1][0]*(1-p);
for(i=2;i<=t;i++)
{
for(j=1;j<=n;j++)
{
if(j>t)break; //如果j>t,t秒最多有t个人
dp[i][j]=dp[i-1][j-1]*p+dp[i-1][j]*(1-p);
}
dp[i][n]=dp[i-1][n]+dp[i-1][n-1]*p; //初始化所有j为n的情况,如果i-1>n,i秒最多有n个人,如果i-1<n,dp[i-1][n]的最初初始化是为0 的,不用考虑。
}
for(j=0;j<=n;j++)
{
if(j>t)
break;
ans+=j*dp[t][j]; //累加t秒有j个人的数学期望
}
printf("%f\n", ans);
return 0;
}