CodeForces 518D - R2D2 and Droid Army(概率dp)

题意: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;  
}  

 

posted @ 2016-10-25 11:10  TianTengtt  阅读(180)  评论(0编辑  收藏  举报