XDU-1043 Boooooom (概率DP)

1043: Boooooom

时间限制: 1 Sec  内存限制: 128 MB  Special Judge

http://acm.xidian.edu.cn/problem.php?id=1043

[提交][状态][讨论版]

题目描述

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

输入

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

接下来为T组数据。

每组数据的第一行为两个整数n和k,其中,1≤n≤20,1≤k≤n.

接下来的一行有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;
}
时间: 2024-10-12 10:00:02

XDU-1043 Boooooom (概率DP)的相关文章

Codeforces 28C [概率DP]

/* 大连热身D题 题意: 有n个人,m个浴室每个浴室有ai个喷头,每个人等概率得选择一个浴室. 每个浴室的人都在喷头前边排队,而且每个浴室内保证大家都尽可能均匀得在喷头后边排队. 求所有浴室中最长队伍的期望. 思路: 概率dp dp[i][j][k]代表前i个浴室有j个人最长队伍是k的概率. 枚举第i个浴室的人数.然后转移的时候其实是一个二项分布. */ #include<bits/stdc++.h> using namespace std; int jilu[55]; double dp[

hdu 3076 ssworld VS DDD (概率dp)

///题意: /// A,B掷骰子,对于每一次点数大者胜,平为和,A先胜了m次A赢,B先胜了n次B赢. ///p1表示a赢,p2表示b赢,p=1-p1-p2表示平局 ///a赢得概率 比一次p1 两次p0*p1 三次 p0^2*p1,即A赢的概率为p1+p*p1+p^2*p1+...p^n*p1,n->无穷 ///即a_win=p1/(1-p);b_win=p2/(1-p); ///dp[i][j]表示a赢了j次,b赢了i次的概率 ///dp[i][j]=dp[i-1][j]*b_win+dp[

hdu 3853 概率DP 简单

http://acm.hdu.edu.cn/showproblem.php?pid=3853 题意:有R*C个格子,一个家伙要从(0,0)走到(R-1,C-1) 每次只有三次方向,分别是不动,向下,向右,告诉你这三个方向的概率,以及每走一步需要耗费两个能量,问你走到终点所需要耗费能量的数学期望: 回头再推次,思想跟以前的做过的类似 注意点:分母为0的处理 #include <cstdio> #include <cstring> #include <algorithm>

hdu4089(公式推导)概率dp

题意:有n人都是仙剑5的fans,现在要在官网上激活游戏,n个人排成一个队列(其中主角Tomato最初排名为m), 对于队列中的第一个人,在激活的时候有以下五种情况: 1.激活失败:留在队列中继续等待下一次激活(概率p1) 2.失去连接:激活失败,并且出队列然后排到队列的尾部(概率p2) 3.激活成功:出队列(概率p3) 4.服务器瘫:服务器停止服务了,所有人都无法激活了(概率p4) 求服务器瘫痪并且此时Tomato的排名<=k的概率. 解法:ans[i][j]表示i个人出于第j个位置要到目的状

poj3071(概率DP)

题意:淘汰赛制,2^n(n<=7)个队员.给出相互PK的输赢概率矩阵.问谁最有可能赢到最后. 解法:ans[i][j]表示第i个队员第j轮胜出的概率.赢到最后需要进行n场比赛.算出每个人赢到最后的ans[i][n].写出序号的二进制发现一个规律,两个队员i.j如果碰到,那么一定是在第get(i,j)场比赛碰到的.get(i,j)计算的是i和j二进制不同的最高位,这个规律也比较明显. 代码: /****************************************************

【Foreign】开锁 [概率DP]

开锁 Time Limit: 10 Sec  Memory Limit: 256 MB Description Input Output Sample Input 4 5 1 2 5 4 3 1 5 2 2 5 4 3 1 5 3 2 5 4 3 1 5 4 2 5 4 3 1 Sample Output 0.000000000 0.600000000 0.900000000 1.000000000 HINT Main idea 一个宝箱内有一个可以开启别的宝箱的钥匙,可以选择k个宝箱,询问能开

POJ 2151 Check the difficulty of problems (概率DP)

题意:ACM比赛中,共M道题,T个队,pij表示第i队解出第j题的概率 ,求每队至少解出一题且冠军队至少解出N道题的概率. 析:概率DP,dp[i][j][k] 表示第 i 个队伍,前 j 个题,解出 k 个题的概率,sum[i][j] 表示第 i 个队伍,做出 1-j 个题的概率,ans1等于, T个队伍,至少解出一个题的概率,ans2 表示T个队伍,至少解出一个题,但不超过N-1个题的概率,最后用ans1-ans2即可. 代码如下: #pragma comment(linker, "/STA

UVALive 6672 Bonus Cards 概率dp

题意呢 就是有两种售票方式 一种是icpc 一种是其他方式 icpc抢票成功的概率是其他方式的2倍…… 这时 一个人出现了 他通过内幕知道了两种抢票方式各有多少人 他想知道自己如果用icpc抢票成功的概率是多少 用acm抢票成功的概率是多少…… 做过不多的概率dp 还在摸索…… dp[i][j]代表第i轮有j个icpc的人已经有票了…… 当然同时i-j个通过其他方式抢票的人也有票了 这就是用同样的函数搜两次的原理…… 优化一次i<=a 一次是把初始化放到for里…… 第一次见这么卡时间的题……

HDU 4599 Dice (概率DP+数学+快速幂)

题意:给定三个表达式,问你求出最小的m1,m2,满足G(m1) >= F(n), G(m2) >= G(n). 析:这个题是一个概率DP,但是并没有那么简单,运算过程很麻烦. 先分析F(n),这个用DP来推公式,d[i],表示抛 i 次连续的点数还要抛多少次才能完成.那么状态转移方程就是 d[i] = 1/6*(1+d[i+1]) + 5/6*(1+d[1]), 意思就是说在第 i 次抛和上次相同的概率是1/6,然后加上上次抛的和这一次,再加上和上次不同的,并且又得从第1次开始计算. 边界就是