1. 程式人生 > >HDU—5985 Lucky Coins(概率)

HDU—5985 Lucky Coins(概率)

連結:

題意:

有多種型別的硬幣,每種型別的硬幣都有一定的數量,現在每次拋硬幣,除去朝下的硬幣,知道最後只剩下一個硬幣或者沒有硬幣,最後的硬幣便是幸運硬幣,求每種型別硬幣成為幸運硬幣的概率。

思路:

 die[i][j]die[i][j] 表示第 ii 種硬幣在前 jj 步內死光光的概率;  alive[i][j]alive[i][j] 表示第 ii 種硬幣在第 jj 步還有至少一個沒死的概率;  num[i]num[i] 表示第 ii 種硬幣的個數;  p[i] 表示第 ii 種硬幣投出正面的概率;

所以:

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

alive[i][j]=1−die[i][j]alive[i][j]=1−die[i][j]

假如第 ii 種硬幣在第 steps+1 步死光,那麼第 i 種硬幣為幸運硬幣的概率為:

 ∑step(alive[i][step]−alive[i][step+1])∗∏nj=1(j==i?1:die[j][step])

其實一直不理解為什麼要用alive相減。可能是因為step+1是由step分下去的吧,換句話說,step步至少

有一個活,會分成在第step+1步全死或者step+1步至少一個活。

​
#include <bits/stdc++.h>
using namespace std;
int n,m,num;
double p;
double die[15][105],alive[15][105];
int main()
{
    int  t;
    cin>>t;
    while(t--)
    {
        cin>>n;
        for(int i=1; i<=n; i++)
        {
            cin>>num>>p;
            for(int k=1; k<=100; k++)
            {
                die[i][k] = pow(1.0-pow(p,k*1.0),num*1.0);
                alive[i][k]=1.0-die[i][k];
            }
        }
        if(n==1)
        {
            cout<<"1.000000"<<endl;
            continue;
        }
        for(int i=1; i<=n; i++)
        {
            double ans = 0;
            for(int k=1; k<=100; k++)
            {
                double temp =1;
                for(int j=1; j<=n; j++)
                {
                    if(i!=j)
                        temp*=die[j][k];
                }
                ans+=(alive[i][k]-alive[i][k+1])*temp;
            }
            printf("%.6f%c",ans,i==n?'\n':' ');
        }
    }
    return 0;
}

​