Card Collector (概率dP)

来源:互联网 发布:求一个矩阵的逆过程 编辑:程序博客网 时间:2024/06/05 22:23

Card Collector

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4126    Accepted Submission(s): 2070
Special Judge


Problem Description
In your childhood, do you crazy for collecting the beautiful cards in the snacks? They said that, for example, if you collect all the 108 people in the famous novel Water Margin, you will win an amazing award. 

As a smart boy, you notice that to win the award, you must buy much more snacks than it seems to be. To convince your friends not to waste money any more, you should find the expected number of snacks one should buy to collect a full suit of cards.
 

Input
The first line of each test case contains one integer N (1 <= N <= 20), indicating the number of different cards you need the collect. The second line contains N numbers p1, p2, ..., pN, (p1 + p2 + ... + pN <= 1), indicating the possibility of each card to appear in a bag of snacks. 

Note there is at most one card in a bag of snacks. And it is possible that there is nothing in the bag.
 

Output
Output one number for each test case, indicating the expected number of bags to buy to collect all the N different cards.

You will get accepted if the difference between your answer and the standard answer is no more that 10^-4.
 

Sample Input
10.120.1 0.4
 

Sample Output
10.00010.500
 

先来讲一下期望这个东西。

E的原始定义是E=p1*x1+p2*x2+... pi表示买xi包面能集齐所有卡片的概率。从实际上说,买n*E包方便面(n非常大),极大可能得到n套卡片。

从理论上说,在理想的情况下,买E包方便面,必然得到1套卡片。



先把问题简化一下,只有一张卡片,其发生的概率是p,集齐这张卡片需要吃方便面的期望是E.

则 E=p*1+(1-p)*(1+E).

虽然把这个公式化简成Ep=1比较好理解,但是要写出多张卡片,就必须先理解 E=p*1+(1-p)*(1+E).

那么定义p为只买了一张卡片,就集齐一套卡片。则(1-p)为买了多张卡片(第一张失败)就集齐一套卡片。这两个事件是对立的。

那么对于买了多张卡片集齐一套卡片中多张卡片是几张呢,(1+E), 理论上说是必然。



对于两张卡片,设(00)表示还未集齐所有卡片到集齐所有卡片(11)需要购买方便面的期望是E(00)。

(10)表示已经集齐第一张卡片,到集齐所有卡片(11)需要构面方便面的期望是E(00)

    E(00)=p1*(1+E(10)) //买了第一包面摸到了第1张卡片,概率是p1,接下来还需要E(10)包方便面

       +p2*(1+E(01))  //买了第一包面摸到了第2张卡片,概率是p1,接下来还需要E(01)包方便面

+(1-p1-p2)(1+E(00)) ////买了第一包面,里面什么也没有,概率是1-p1-p2,接下来还需要E(00)包方便面



E(01)=p1*(1+E(11)) +(1-p1-p2) *(1+E(01))

     E(10)=p2*(1+E(11))+(1-p1-p2)*(1+E(10))

    E(11)=0 //已经集齐了,当然只要买0包方便面就行了。



所以对于n张卡片。 x 是一个二进制数

  E(x)=∑(pi*(1+E(y))+(1-∑pi)*(1+E(x)) i表示x的第i位等于0.y表示讲x的第i位从0变成1以后的二进制数。

   解一下方程 E(x)=(1+∑(pi*E(y)))/(∑pi)

这就是概率动态规划的状态转移方程了。

E(1111111..n个1)=0 ,临界状态。

       E(00000...n个0) =? 目标状态。


 

#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<queue>#define VN 300#define eps 1e-8using namespace std;int T;int n;double dp[1<<21];double p[21];int main(){    while(scanf("%d",&n)!=EOF)    {        for(int i=0;i<n;i++)        {            scanf("%lf",&p[i]);        }        dp[(1<<n)-1]=0;        for(int i=(1<<n)-2;i>=0;i--)        {            double x=0,sum=1;            for(int j=0;j<n;j++)            {                if(!(i&(1<<j)))                {                    x+=p[j];                    sum += p[j]*dp[i|(1<<j)];                }            }            dp[i] = sum/x;        }        printf("%.5lf\n",dp[0]);    }    return 0;}


0 0
原创粉丝点击