CodeForces - 518D (概率dp)

dp[i][j]表示第 i 秒时有 j 个人的概率,j<=n,j<=i(刚开始用dp[i][j]表示第 i 秒时第 j 个人上电梯,不仅复杂度高,而且还不好得出期望,属实nt)

 

可以从两种状态转移到当前状态,

一是我之前得到 j-1个人,这一次在加上一个人,即dp[i-1][j-1]*p,

另一种是我之前已经得到 j 个人了,我这一次电梯不上人,这种情况是dp[i-1][j]*(1-p),需要注意如果 j==n,那么电梯无法在上人了,此时就是dp[i-1][j]。

#include<cstdio>
#include<iostream>
#include<cstring>

using namespace std;

const int maxn=2e3+10;

double dp[maxn][maxn];
int main()
{
    int n,t;
    double p;
    cin>>n>>p>>t;
    dp[0][0]=1;
    for(int i=1;i<=t;i++){
        dp[i][0]=dp[i-1][0]*(1-p);
        for(int j=1;j<=min(i,n);j++){
            if(j==n) dp[i][j]=dp[i-1][j-1]*p+dp[i-1][j];
            else dp[i][j]=dp[i-1][j-1]*p+dp[i-1][j]*(1-p);
        }
    }
    double ans=0;
    for(int i=1;i<=n;i++)
        ans+=i*dp[t][i];
    printf("%.8f",ans);
}

 

posted @ 2020-11-16 20:19  Npunchman  阅读(90)  评论(0)    收藏  举报