HDU4336 Card Collector【容斥原理】

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=4336


题目大意:

每包零食里有一张卡牌,总共有N种不同的卡牌,得到这N种卡牌的概率分别为P[i](1 <= i <= N)。

求收集到所有卡牌的期望是多少。


思路:

Pi表示得到第i张卡牌的概率,Ei表示得到第i张卡的期望。

假设现在有两张卡牌,由题意可知:

E1 = 1/P1,E2 = 1/P2,E12(表示肯定买到1或2其中一包的期望) = 1/(P1+P2)。

当我们计算E1和E2的时候,E12是重复计算了2次,应该减去一次。根据容斥定理可知:

E = E1 + E2 - E12。

同理,三张牌的时候:

E = E1 + E2 + E3 - E12 - E13 - E23 + E123。

以此类推,当计算期望中的各项的时候,如果该项为奇数项(奇数张卡的期望),则加上该项。

如果该项为偶数项2(偶数项卡的期望),则减去该项。


AC代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;

double P[50];
int N;

double Solve()
{
    double xh = 0;
    for(int i = 1; i < (1 << N); ++i)   //遍历2^N种情况  从00…01 到 11…11
    {
        double sum = 0;
        int odd = 0;
        for(int j = 0; j < N; ++j)      //对于i(每种情况),计算i的二进制为1的位数
        {
            if((1<<j) & i)      //i从右往左数对应第j位上是否为1
            {
                odd++;          //二进制为1的位数
                sum += P[j+1];  //将为1项的概率加起来。
            }
        }
        if(odd & 1) //奇数项加,偶数项减
            xh += 1/sum;
        else
            xh -= 1/sum;
    }
    return xh;

}
int main()

{
    while(~scanf("%d",&N))
    {
        for(int i = 1; i <= N; ++i)
            scanf("%lf",&P[i]);
        printf("%.6lf\n",Solve());  //注意lf 和 f
    }

    return 0;
}


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值