• hdu4336 Card Collector 概率dp(或容斥原理?)



    题意:

    买东西集齐全套卡片赢大奖。每个包装袋里面有一张卡片或者没有。

    已知每种卡片出现的概率 p[i],以及所有的卡片种类的数量 n(1<=n<=20)。

    问集齐卡片需要买东西的数量的期望值。



    一开始,自己所理解的期望值是原来学过的  一个值*它自身发生的概率,这没错,但是不知道在这一题里面 那个值是多少

    经过重重思考和挣扎最后明白了,这一题中,n就是那个值,也是你要求的,感觉理解这个好难,但是好重要,

    此题中,将n设置为 dp[0]


    可以这样想,你要买sum包,才能集齐n种卡片,那么 你最后买的一包一定中奖,即一定是n种中的一种,

    用状态压缩表示,dp[1111111]就表示,你现在可以要n包中的一包,也就是可以变成0111111,1011111,1101111.。。。1111110中的一种状态

    dp[1111111]=上面列的所有的状态 乘以 中0那包的概率,即dp[i]+=dp[i|(1<<j)]*p[j];

    而dp[1111111]表示刚开始,你可以中任一种,它的期望值是0,因为你现在任一种都没有,

    dp[0000000]即 dp[0] 则表示现在每一包都有,你已经不用买了,从直观上就可以理解为每位都是0,你没有选择了,


    那么,给初值dp[(1<<n)-1]=0,

    从这开始,对每一种状态,列举它的每一位,如果是0,则可以变成该位是1的状态,


    恩,,差不多就是这样吧。。

    不知道自己的理解是否正确 觉得关键还是期望值的意义和最后的结果的意义不太能理解。。

    反正我只能理解到这一步了,望批评指正交流


    关于容斥原理的解法,还没怎么想,大家可以百度下 ,看起来好简单的样子


    下面是参考代码,大家感受下


    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<string>
    using namespace std;
    
    double p[25],dp[1<<20];
    
    int main()
    {
        int i,j,n;
        double pp;
        while(~scanf("%d",&n))
        {
            for(i=0;i<n;i++)
                scanf("%lf",&p[i]);
            dp[(1<<n)-1]=0;
            for(i=(1<<n)-2;i>=0;i--)//枚举所有状态
            {
                pp=0;
                dp[i]=1;
                for(j=0;j<n;j++)//对每一位枚举
                {
                    if(!(i&(1<<j)))//该位是0
                    {
                        dp[i]+=dp[i|(1<<j)]*p[j];
                        pp+=p[j];
                    }
                }
                dp[i]/=pp;//可以到达i这种状态的状态都找到了 在循环里累加的是期望值 要除概率和
            }
            printf("%lf
    ",dp[0]);
        }
        return 0;
    }
    



  • 相关阅读:
    【作业7】完成调查问卷
    用博客园第一周
    讲座观后感
    调查问卷
    第十一周·前端学习笔记--正则表达式
    调查问卷
    思维导图
    讲座心得1
    第一次作业(8.学习进度表)
    第一次作业(7.问卷调查)
  • 原文地址:https://www.cnblogs.com/pangblog/p/3246590.html
Copyright © 2020-2023  润新知