zoukankan      html  css  js  c++  java
  • 【HDU4336】Card Collector-Min-Max容斥

    测试地址:Card Collector
    题目大意:n张牌,每次有pi的概率抽到第i张牌,问抽到过所有的牌所需的期望次数。
    做法:本题需要用到Min-Max容斥。
    很久之前我写过这题的状压DP写法,那个做法时间复杂度为O(n2n),空间复杂度为O(2n),而今天本人学会了一种新的做法:Min-Max容斥,这个做法比状压DP更加优美一些。
    Min-Max容斥,又称最值反演,是指下面这个式子:
    max{S}=TS(1)|T|+1min{T}
    其中S,T为集合,max{S},min{S}表示集合S的最大元素和最小元素。先别急着质问这个式子有什么卵用,我们先看看这个式子是怎么来的。
    尝试证明右边等于左边。令x=max{S},我们有一个关于集合T的映射f(T),定义为:若集合T中包含x,则f(T)就是T去掉x后的集合,否则f(T)就是T加上x后的集合。显然这个映射有这样一个性质:f(f(T))=T,那么Tf(T)就是一一对应的关系。除去空集和{x}两个集合的对应,其它的对应关系中,两个集合的大小正好差1,而它们的最小值都相同,所以根据上面的式子,它们相互抵消。而空集没有最小值,所以整个右边式子的值就等于{x}这个集合的贡献:x,即max{S}
    说了这么多,这个式子在这题中有什么用呢?Min-Max容斥有一个非常重要的推论:
    E[max{S}]=TS(1)|T|+1E[min{T}]
    其中E[x]表示x的期望,证明应该显然。而这个式子更常用的意义是这样的:给S中每个元素随机赋值,表示这个元素第一次被取到的时间,那么E[min{S}]的意义就变成S中第一个被取的元素的期望被取时间,E[max{S}]的意义就变成S中最后一个被取的元素的被取期望时间,也就是S中所有元素都被取过所需的期望时间。我们发现这个时间就相当于取的次数,所以也就是期望次数。
    这个推论在这题中就非常有用了,因为本题中E[min{S}]=1iSpi,所以我们只需O(2n)枚举集合即可算出E[max{S}],空间复杂度也很小(O(n)),可以说是比状压DP优美很多了。
    以下是本人代码:

    #include <bits/stdc++.h>
    using namespace std;
    int n;
    double p[25],ans;
    
    void solve(int step,int cnt,double totp)
    {
        if (step>n)
        {
            if (!cnt) return;
            double f=(cnt%2)?1.0:-1.0;
            ans+=f/totp;
            return;
        }
        solve(step+1,cnt,totp);
        solve(step+1,cnt+1,totp+p[step]);
    }
    
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            for(int i=1;i<=n;i++)
                scanf("%lf",&p[i]);
            ans=0.0;
            solve(1,0,0.0);
            printf("%.6lf
    ",ans);
        }
    
        return 0;
    }
  • 相关阅读:
    【NOIP2007提高组T4】树网的核-Floyd最短路+枚举
    【NOIP2007提高组T4】树网的核-Floyd最短路+枚举
    【NOIP2008提高组T4】双栈排序-二分图染色
    【NOIP2008提高组T4】双栈排序-二分图染色
    【NOIP2010提高组T4】引水入城-搜索+DP
    【NOIP2010提高组T4】引水入城-搜索+DP
    【NOIP2011提高组T5】聪明的质监员-二分答案+前缀和
    【NOIP2011提高组T5】聪明的质监员-二分答案+前缀和
    POJ 1113 Wall
    BZOJ 1412 狼和羊的故事
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9793316.html
Copyright © 2011-2022 走看看