Card Collector

Card Collector

有n种卡,每一卡包有概率\(p_i\)出现卡i,只会出现一张以下的卡,询问卡包的期望数包含所有种类的卡,\(1 <= N <= 20\)

法一:容斥原理

注意到数据范围很小,再此我们能很轻松地求出一种卡摸到的期望,而此时摸到的期望包含了其他的部分,于是考虑容斥。

不难有一种卡i,其摸到的期望数为\(\frac{1}{p_i}\),而对于摸到卡i,或者j的期望数不难得知,即把它们看成一个整体\(\frac{1}{p_i+p_j}\),于是我们可以以此为容斥依据,进行容斥即可。

参考代码:

#include <iostream>
#include <cstdio>
#define il inline
#define ri register
using namespace std;
double w[20];
int main(){
    double sxr,ans;
    int n,i,j,li,tot;
    while(scanf("%d",&n)!=EOF){
        for(i=0;i<n;++i)scanf("%lf",&w[i]);
        li=1<<n,ans=0;
        for(i=1;i<li;++i){
            tot&=0,sxr=0;
            for(j=0;j<n;++j)
                if(i>>j&1)sxr+=w[j],++tot;
            if(tot&1)ans+=1/sxr;
            else ans-=1/sxr;
        }printf("%.5lf\n",ans);
    }
    return 0;
}

法二:无后效性处理

注意到为期望题,而样本空间无限大,考虑无后效性做法,即以期望代无限状态,设\(E(x)\)表示已经摸到x对应二进制的卡种数的期望卡包数(如\(E(3)\)表示已经摸到第1中卡和第二种卡的卡包数期望),于是不难有转移

\[E(x)=1+\sum E(x)p_i+\sum E(y)p_j\]

其中\(E(x)p_i\)表示摸到已经摸过的卡,概率分别为\(p_i\),y则是对应二进制位已经把没摸过的卡记录下来,概率分别为\(p_j\)

例如,只有2种卡,设\(p_0\)为没有摸到任何卡的概率

\[E(0)=1+E(0)p_0+E(1)p_1+E(2)p_2\]

\[E(1)=1+E(1)(p_0+p_1)+E(3)p_2\]

\[E(2)=1+E(2)(p_0+p_2)+E(3)p_1\]

\[E(3)=0\]

于是对一般式变换一下,我们有

\[E(x)=\frac{1+\sum E(y)p_j}{(1-\sum p_i)}\]

以此为递推依据记忆化搜索即可。

参考代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#define il inline
#define ri register
using namespace std;
int n;double w[21];
double dp[1048576];
il double search(int);
int main(){
    int i,li;
    while(scanf("%d",&n)!=EOF){
        w[n]=1;for(i=0;i<n;++i)scanf("%lf",&w[i]),w[n]-=w[i];
        memset(dp,-127,sizeof(dp)),li=(1<<n)-1,dp[li]=0;
        printf("%.5lf\n",search(0));
    }return 0;
}
il double search(int er){
    if(dp[er]>=0)return dp[er];
    int i;double mom(1-w[n]),son(1);
    for(i=0;i<n;++i)
        if(er>>i&1)mom-=w[i];
        else son+=search(er|1<<i)*w[i];
    return dp[er]=son/mom;
}

转载于:https://www.cnblogs.com/a1b3c7d9/p/10839273.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值