HDU-5985-Lucky Coins

来源:互联网 发布:在u盘上安装linux系统 编辑:程序博客网 时间:2024/06/05 01:12

ACM模版

描述

描述

题解

这场比赛好不顺啊,好多期望概率的涉及,╮(╯▽╰)╭哎~~~

die[i][j] 表示第 i 种硬币在前 j 步内死光光的概率;
alive[i][j] 表示第 i 种硬币在第 j 步还有至少一个没死的概率;
num[i] 表示第 i 种硬币的个数;
p[i] 表示第 i 种硬币投出正面的概率……

则:

die[i][j]=(1p[i]j)num[i]
alive[i][j]=1die[i][j]

假如第 i 种硬币在第 steps+1 步死光,那么第 i 种硬币为幸运硬币的概率为:

luck[i]=steps=1MAX_STEPS(alive[i][steps]alive[i][steps+1])j=1n([j=i] ? 1:die[j][steps])

另外需要注意的是,样例中有提示,当只有一种硬币时,特判一下,概率视为 1.000000

代码

#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;const int MAX_STAPES = 75;const int MAXN = 15;int n;int num[MAXN];double p[MAXN];double die[MAXN][MAX_STAPES + 5];double alive[MAXN][MAX_STAPES + 5];double luck[MAXN];void solve(){    for (int i = 0; i < MAXN; i++)    {        luck[i] = 0.0;    }    for (int i = 0; i < n; i++)    {        double tmp = p[i];        for (int j = 1; j <= MAX_STAPES; j++)        {            die[i][j] = pow(1 - tmp, num[i]);            alive[i][j] = 1 - die[i][j];            tmp *= p[i];        }    }    for (int i = 0; i < n; i++)    {        for (int j = 1; j < MAX_STAPES; j++)        {            double tmp = 1.0;            for (int k = 0; k < n; k++)            {                if (k != i)                {                    tmp *= die[k][j];                }            }            luck[i] += (alive[i][j] - alive[i][j + 1]) * tmp;        }    }}int main(){    int T;    scanf("%d", &T);    while (T--)    {        scanf("%d", &n);        for (int i = 0; i < n; i++)        {            scanf("%d%lf", &num[i], &p[i]);        }        if (n == 1)        {            puts("1.000000");            continue;        }        solve();        for (int i = 0; i < n; i++)        {            printf("%.6f%c", luck[i], (i == n - 1) ? '\n' : ' ');        }    }    return 0;}