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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值