LightOJ 1342 Aladdin and the Magical Sticks 期望

Aladdin and the Magical Sticks LightOJ - 1342

有两种棍子,一种摸过之后就可以辨别,另外一种无法辨别,总共有 nn 个棍子,每次从中间摸一个出来,假如每个棍子都摸出来过,那么结束,否则该棍子仍然要放回去进行下一轮操作。对于摸过一次后就可以辨别的棍子类型,之后选择都不再摸,也就是说,设可以选择的棍子集合为 A\mathcal{A},第一次从中等概率地摸一个棍子 ii ,假如是可辩别的,那么把这个棍子踢出棍子集合,即 AA/i\mathcal{A}\gets \mathcal{A}/i ,然后在新的集合 A\mathcal{A} 中重新进行上述操作,直到所有棍子都被摸过至少一次;假如不可辨别,那么集合 A\mathcal{A} 不变,重新操作。

每个棍子都有对应的重量 wiw_i,问操作结束时摸过的棍子的重量期望是多少?

类似 邮票收集问题

假如所有的棍子都是不可辨别的,先假设重量都是 11 的话,那么总的期望应该是 nHnn\cdot H_n,其中 Hn=i=1n1iH_n=\sum_{i=1}^n{\frac{1}{i}}平均下来一个不可辨别的棍子对应的期望是 HnH_n,而对于可辨别的棍子来说,他们的期望都是 11,所以分开计算即可。

(但是其实上面这个平均操作我觉得并不能从直观意义上进行理解,具体可以看看 Wikipedia 的推导过程就可以感受得到)

代码如下:

#include<iostream>
#include<cstdio>
//#define WINE
using namespace std;
int T,iCase,n,a,b;
double res,H[5506];
int main(){
#ifdef WINE
    freopen("data.in","r",stdin);
#endif
    for(int i=1;i<=5005;i++)
        H[i]=H[i-1]+1.0/i;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        res=0;
        for(int i=0;i<n;i++){
            scanf("%d%d",&a,&b);
            if(b==1)res+=a;
            else res+=a*H[n];
        }
        printf("Case %d: %.8lf\n",++iCase,res);
    }
    return 0;
}

在这里插入图片描述

posted @ 2020-03-26 13:03  winechord  阅读(95)  评论(0编辑  收藏  举报