码迷,mamicode.com
首页 > 其他好文 > 详细

XDU-1043 Boooooom (概率DP)

时间:2016-05-13 01:07:47      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:

1043: Boooooom

时间限制: 1 Sec  内存限制: 128 MB  Special Judge
http://acm.xidian.edu.cn/problem.php?id=1043
[提交][状态][讨论版]

题目描述

BoomUUZ发飙了。参加ACM的培训本应该有n个人,今天却只来了那么一点点。已知每个学生能来上课的概率为Pi(1in),当上课人数少于k时,UUZ会发飙,一旦UUZ发飙,那么以后的课(包括这节课)就都不上了,而如果不发飙,则UUZ还会开下一节课。那么,UUZ能为大家开课的期望大约是多少堂呢?精确到0.1就可以了。

输入

有多组输入数据,第一行为一个数字T,代表有T组输入数据 (0<T10)

接下来为T组数据。

每组数据的第一行为两个整数nk,其中,1n201kn.

接下来的一行有n个整数1位小数(大于0小于1),表示这n个学生来上课的概率。

输出

对于每组数据,在一行上输出一个实数,表示UUZ上课的期望值。

只要答案的相对误差在10-6以内,或绝对误差在0.1以内,都判为正确。

样例输入

1
3 1
0.1 0.1 0.1

样例输出

0.4

设dp[i][j]表示前i个人中有j个人来上课的概率,初始:dp[0][0]=0;

态转移方程为:dp[i][j]=dp[i-1][j]*(1-p[i])+dp[i-1][j-1]*p[i];

计算n个人中来上课的人数大于等于k时的概率为sum

则可求的上课天数的期望为:sum+sum^2+…+sum^x,(x→

等比数列求和得:sum/(1-sum)

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

int n,k;
double p[25];
long double dp[25][25],sum;//dp[i][j]表示前i个人中有j个人来上课的概率

int main() {
    int T;
    scanf("%d",&T);
    while(T-->0) {
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;++i) {
            scanf("%lf",p+i);
        }
        dp[0][0]=1;
        for(int i=1;i<=n;++i) {
            for(int j=0;j<i;++j) {
                dp[i][j]=dp[i-1][j]*(1-p[i])+dp[i-1][j-1]*p[i];
            }
            dp[i][i]=dp[i-1][i-1]*p[i];
        }
        sum=0;//sum表示n个人中来上课的人数大于等于k时的概率
        for(int i=k;i<=n;++i) {
            sum+=dp[n][i];
        }
        printf("%.2lf\n",double(sum/(1-sum)));
    }
    return 0;
}


XDU-1043 Boooooom (概率DP)

标签:

原文地址:http://blog.csdn.net/idealism_xxm/article/details/51345525

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!