[hdu5985]概率题的推导

原创 2016年11月30日 23:04:09

题目描述

Bob has collected a lot of coins in different kinds. He wants to know which kind of coins is lucky. He finds out a lucky kind of coins by the following way. He tosses all the coins simultaneously, and then removes the coins that come up tails. He then tosses all the remaining coins and removes the coins that come up tails. He repeats the previous step until there is one kind of coins remaining or there are no coins remaining. If there is one kind of coins remaining, then this kind of coins is lucky. Given the number of coins and the probability that the coins come up heads after tossing for each kind, your task is to calculate the probability for each kind of coins that will be lucky.

算法思路

  1. 这一题在比赛的时候我想的太多了,切分的子问题太多反而导致求解变得十分困难,最后导致我们没有A下这一题,可以说责任在我。
  2. 思路的话十分简单,首先,我们先计算出到达第k步的时候硬币i死亡的概率
    kill[i][j]=(1p[i]j)num[i]

    我们就可以计算出到达第i步之后i存活的概率
    recv[i][j]=1kill[i][j]

    那么,我们就可以得到某一个硬币i成为lucky coins的概率
    ans[i]=j=1max(recv[i][j]recv[i][j+1)k=0,kinkill[k][j]

    这个max是如何确定呢,我们知道所有的概率都在0.4-0.6之间,而总的硬币的个数在100000之内,我们就可以计算收敛的速度了。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;

#define MAXN 75
#define MAXM 15

int t,n;
int num[MAXM];
double p[MAXM];
double killed[MAXM][MAXN+5];
double recv[MAXM][MAXN+5];
double ans[MAXM];

void Solve()
{
    int i,j,k;

    for(i=0;i<MAXM;i++)
        ans[i] = 0.0;

    if(n==1){
        printf("%.6f\n",1.0);
        return;
    }

    for(i=0;i<n;i++){
        double tmp = p[i];
        for(j=1;j<=MAXN;j++){
            killed[i][j] = pow(1-tmp,num[i]);
            recv[i][j] = 1 - killed[i][j];
            tmp *= p[i];
        }
    }

    for(i=0;i<n;i++){
        for(j=1;j<MAXN;j++){
            double tmp = 1.0;
            for(k=0;k<n;k++){
                if(k!=i)
                    tmp *= killed[k][j];
            }
            ans[i] += (recv[i][j]-recv[i][j+1])*tmp;
        }
    }

    for(i=0;i<n;i++)
        printf("%.6f%c",ans[i],(i==n-1)?'\n':' ');

    return;
}

int main()
{
    freopen("input","r",stdin);
    int i;

    scanf("%d",&t);

    while(t--){
        scanf("%d",&n);

        for(i=0;i<n;i++)
            scanf("%d%lf",&num[i],&p[i]);

        Solve();
    }
    return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

HDU-5985-Lucky Coins-2016青岛站D题-数学推导

题目链接题目大意:给你n种硬币,并给你每种硬币的个数和正面朝上的概率。每次将所有的硬币投掷一下。背面朝上的抛弃。直到只剩下一种硬币或者没有硬币。最后剩下的那种硬币叫幸运硬币,问每种硬币成为幸运硬币的概...

HDU5985Lucky Coins 【数学题】

Lucky CoinsTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total...

HDU-5985-Lucky Coins(概率)

链接:http://acm.hdu.edu.cn/showproblem.php?pid=5985 收敛概率,注意n==1的情况。 #include #define MAXN 107 using...

hdu 5985 Lucky Coins (概率)

好有趣的一个题,真是让人进一步理解的概率问题,如果太小选择忽略,这个题目中很简单就能找到小的那个,0.5的30次方在double中已经为0了,为了保险起见可以选择100. 令两个函数f[i]...

HDU-5985-Lucky Coins

ACM模版描述题解这场比赛好不顺啊,好多期望概率的涉及,╮(╯▽╰)╭哎~~~设 die[i][j]die[i][j] 表示第 ii 种硬币在前 jj 步内死光光的概率; 设 alive[i][j]...
  • f_zyj
  • f_zyj
  • 2017年10月16日 16:18
  • 103

HDU 5985 Lucky Coins(概率)

Problem DescriptionBob has collected a lot of coins in different kinds. He wants to know which kind ...
  • so_so_y
  • so_so_y
  • 2017年10月14日 22:20
  • 75

HDU 5985 概率问题

概率问题题意:​ 有n种硬币,现在有一个方法可以得出一个或者一种lucky硬币,所有硬币抛下然后去掉背面朝上的,继续抛直到只剩一种硬币或者没有硬币为止。问每一种硬币成为lucky的概率是多少。思路...

HDU-5700-区间交

Problem Description小A有一个含有n个非负整数的数列与m个区间。每个区间可以表示为li,ri。 它想选择其中k个区间, 使得这些区间的交的那些位置所对应的数的和最大。 例如样例中...
  • f_zyj
  • f_zyj
  • 2016年06月01日 03:29
  • 362

hdu 5667 Sequence【矩阵快速幂】

Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total S...

51nod 1165 整边直角三角形的数量

51nod 1165 整边直角三角形的数量
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[hdu5985]概率题的推导
举报原因:
原因补充:

(最多只允许输入30个字)