Codeforces518 D. Ilya and Escalator

传送门:>Here<

题意:有n个人排队做电梯,每个人必须等前面的人全部上了以后才能上。对于每秒钟,有p的概率选择上电梯,(1-p)的概率选择不上电梯。现在问t秒期望多少人上电梯

解题思路:

  期望DP。

  $f[i][j]$表示第i秒上了j个人的概率。

  $f[1][1] = p, f[1][0] = (1 - p)$,并且$f[i][0]$都需要初始化。($* (1 - p)$)

  这题好像和普通的期望DP不太一样啊,因为f数组设的是概率而不是期望。这样设的话答案就应该是$sumlimits_{i = 0}^{Min(n, t)}f[t][i] * i$

  考虑如何转移:

  第i秒的时候不上人:$ f[i-1][j] * (1 - p) $

  第i秒的时候上人:$ f[i-1][j-1] * p $

  因此对于一般情况:$$f[i][j] = f[i-1][j] * (1 - p) + f[i-1][j-1] * p$$

  另外,总共就n个人,如果$t > n$就需要特判了:$$f[i][n] = f[i-1][n] + f[i-1][n-1]*p$$

Code

  还是边界条件!对于$f[i][j]$,由于每秒最多上一个人,所以$j$是不可能大于$i$的,要特判一下。

 

/*By QiXingzhi*/
#include <cstdio>
#include <queue>
#define  r  read()
#define  Max(a,b)  (((a)>(b)) ? (a) : (b))
#define  Min(a,b)  (((a)<(b)) ? (a) : (b))
using namespace std;
typedef long long ll;
const int N = 2010;
const int INF = 1061109567;
inline int read(){
    int x = 0; int w = 1; register int c = getchar();
    while(c ^ '-' && (c < '0' || c > '9')) c = getchar();
    if(c == '-') w = -1, c = getchar();
    while(c >= '0' && c <= '9') x = (x << 3) +(x << 1) + c - '0', c = getchar();
    return x * w;
}
int n,t;
double p,f[N][N],cur,ans;
int main(){
//    freopen(".in", "r", stdin);
    scanf("%d %lf %d",&n,&p,&t);
    f[1][1] = p;
    f[1][0] = 1-p;
    for(int i = 2; i <= t; ++i){
        f[i][0] = f[i-1][0] * (1-p);
    }
    for(int i = 2; i <= t; ++i){
        for(int j = 1; j <= n; ++j){
            if(j > i){
                break;
            }
            f[i][j] = f[i-1][j]*(1-p) + f[i-1][j-1]*p;
        }
        f[i][n] = f[i-1][n] + f[i-1][n-1] * p;
    }
    for(int i = 0; i <= n; ++i){
        if(i > t) break;
        ans += f[t][i] * i;
    } 
    printf("%.8lf", ans);
    return 0;
}
原文地址:https://www.cnblogs.com/qixingzhi/p/9347056.html