HDU5985Lucky Coins 【数学题】

来源:互联网 发布:圣人不出门知天下事 编辑:程序博客网 时间:2024/06/01 14:33
Lucky CoinsTime Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 233    Accepted Submission(s): 75Problem DescriptionBob 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.InputThe first line is the number of test cases. For each test case, the first line contains an integer k representing the number of kinds. Each of the following k lines describes a kind of coins, which contains an integer and a real number representing the number of coins and the probability that the coins come up heads after tossing. It is guaranteed that the number of kinds is no more than 10, the total number of coins is no more than 1000000, and the probabilities that the coins come up heads after tossing are between 0.4 and 0.6.OutputFor each test case, output a line containing k real numbers with the precision of 6 digits, which are the probabilities of each kind of coins that will be lucky.Sample Input311000000 0.521 0.41 0.632 0.42 0.52 0.6Sample Output1.0000000.210526 0.4736840.124867 0.234823 0.420066Source2016ACM/ICPC亚洲区青岛站-重现赛(感谢中国石油大学)

die[i][j]=第i种硬币在前j步内死关的概率
alive[i][j]=第i种硬币第j步还没死光
设p = 硬币投出正面的概率,n为这种硬币个数
die[i][j] = (1 - p^j)^n
alive[i][j] = 1 - die[i][j]
假如第i种硬币 在第step+1步死光
那成为luck硬币的概率为 : (alive[i][step]-alive[i][step+1])*nj=1(j==i?1:die[j][step])
枚举step 累加在一起即可

注意当只有一种硬币时 特判概率为1(题面完全没讲到…..)

#include<iostream>#include<cstdlib>#include<cstdio>#include<string>#include<vector>#include<deque>#include<queue>#include<algorithm>#include<set>#include<map>#include<stack>#include<ctime>#include <string.h>using namespace std;#define ll long long#define pii pair<int,int>#define INF 10000000007const int N = 11;const int maxSteps = 300;double die[N][maxSteps];//die[i][j]=第i种硬币前j步死概率double alive[N][maxSteps];//alive[i][j]=第i种硬币第j步还没死光double quickMulti(double p,int n){    double ans=1;    while(n){        if(n&1){            ans*=p;        }        n>>=1;        p*=p;    }    return ans;}void initCoin(int t,int n,double p){    double nowP=p;    for(int step=1;step<maxSteps;++step){        die[t][step]=quickMulti(1-nowP,n);        nowP*=p;    }    for(int step=1;step<maxSteps;++step){        alive[t][step]=1-die[t][step];    }}void slove(int kinds){    for(int i=0;i<kinds;++i){        double ans=0;        for(int step=1;step<maxSteps-5;++step){            double tmp=alive[i][step]-alive[i][step+1];            for(int j=0;j<kinds;++j){                if(j!=i){                    tmp*=die[j][step];                }            }            ans+=tmp;        }        printf("%.6f",ans);        if(i!=kinds-1){            putchar(' ');        }    }    putchar('\n');}int main(){    //freopen("/home/lu/Documents/r.txt","r",stdin);    int T;    scanf("%d",&T);    while(T--){        int kinds;        scanf("%d",&kinds);        for(int i=0;i<kinds;++i){            int n;            double p;            scanf("%d%lf",&n,&p);            initCoin(i,n,p);        }        if(kinds==1){            puts("1.000000");        }        else{            slove(kinds);        }    }    return 0;}
0 0
原创粉丝点击