zoukankan      html  css  js  c++  java
  • HDU 4336 Card Collector 期望dp+状压

    题目链接:

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

    Card Collector

    Time Limit: 2000/1000 MS (Java/Others)
    Memory Limit: 32768/32768 K (Java/Others)
    #### 问题描述 > In your childhood, do you crazy for collecting the beautiful cards in the snacks? They said that, for example, if you collect all the 108 people in the famous novel Water Margin, you will win an amazing award. > > As a smart boy, you notice that to win the award, you must buy much more snacks than it seems to be. To convince your friends not to waste money any more, you should find the expected number of snacks one should buy to collect a full suit of cards.

    输入

    The first line of each test case contains one integer N (1 <= N <= 20), indicating the number of different cards you need the collect. The second line contains N numbers p1, p2, ..., pN, (p1 + p2 + ... + pN <= 1), indicating the possibility of each card to appear in a bag of snacks.

    Note there is at most one card in a bag of snacks. And it is possible that there is nothing in the bag.

    输出

    Output one number for each test case, indicating the expected number of bags to buy to collect all the N different cards.

    You will get accepted if the difference between your answer and the standard answer is no more that 10^-4.

    样例输入

    1
    0.1
    2
    0.1 0.4

    样例输出

    10.000
    10.500

    题意

    小时候买零食的时候,里面都会附带一张卡片(或没有),现在告诉你每包零食里面每一种卡片出现的概率,问你集齐这n类卡片需要买的零食的期望包数。

    题解

    由于卡片种类最多就20多种,所以状压一下从dp[(1<<n)-1]地推到dp[0]就可以了。
    dp[i]表示已经集齐状态为i的卡片,平均还要买多少包才能集齐所有的。
    转移方程:dp[i]=(1-sp)*dp[i]+sigma(pro[j]*dp[i^(1<<j)])+1(这里要保证i&(1<<j)==0,并且sp=sigma(pro[j]).)
    移项得:dp[i]=sigma(pro[j]*dp[i^(1<<j)]+1)/(1-(1-sp))

    #include<map>
    #include<set>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<ctime>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<bitset>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<functional>
    using namespace std;
    #define X first
    #define Y second
    #define mkp make_pair
    #define lson (o<<1)
    #define rson ((o<<1)|1)
    #define mid (l+(r-l)/2)
    #define sz() size()
    #define pb(v) push_back(v)
    #define all(o) (o).begin(),(o).end()
    #define clr(a,v) memset(a,v,sizeof(a))
    #define bug(a) cout<<#a<<" = "<<a<<endl
    #define rep(i,a,b) for(int i=a;i<(b);i++)
    #define scf scanf
    #define prf printf
    
    typedef __int64 LL;
    typedef vector<int> VI;
    typedef pair<int,int> PII;
    typedef vector<pair<int,int> > VPII;
    
    const int INF=0x3f3f3f3f;
    const LL INFL=0x3f3f3f3f3f3f3f3fLL;
    const double eps=1e-9;
    
    const double PI = acos(-1.0);
    
    //start----------------------------------------------------------------------
    
    double dp[1<<21];
    
    double pro[22];
    int n;
    
    int main() {
        while(scf("%d",&n)==1&&n){
            rep(i,0,n){
                scf("%lf",&pro[i]);
            }
            dp[(1<<n)-1]=0.0;
            for(int i=(1<<n)-2;i>=0;i--){
                dp[i]=0;
                double sp=0;
                for(int j=0;j<n;j++){
                    if(i&(1<<j)) continue;
                    sp+=pro[j];
                    dp[i]+=pro[j]*dp[i^(1<<j)];
                }
                dp[i]+=1;
                dp[i]/=sp;
            }
            prf("%.5lf
    ",dp[0]);
        }
        return 0;
    }
    
    //end-----------------------------------------------------------------------
    

    容斥也可以做:

    #include<map>
    #include<set>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<ctime>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<bitset>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<functional>
    using namespace std;
    #define X first
    #define Y second
    #define mkp make_pair
    #define lson (o<<1)
    #define rson ((o<<1)|1)
    #define mid (l+(r-l)/2)
    #define sz() size()
    #define pb(v) push_back(v)
    #define all(o) (o).begin(),(o).end()
    #define clr(a,v) memset(a,v,sizeof(a))
    #define bug(a) cout<<#a<<" = "<<a<<endl
    #define rep(i,a,b) for(int i=a;i<(b);i++)
    #define scf scanf
    #define prf printf
    
    typedef __int64 LL;
    typedef vector<int> VI;
    typedef pair<int,int> PII;
    typedef vector<pair<int,int> > VPII;
    
    const int INF=0x3f3f3f3f;
    const LL INFL=0x3f3f3f3f3f3f3f3fLL;
    const double eps=1e-9;
    
    const double PI = acos(-1.0);
    
    //start----------------------------------------------------------------------
    
    double pro[22];
    int n;
    
    int main() {
        while(scf("%d",&n)==1&&n){
            rep(i,0,n){
                scf("%lf",&pro[i]);
            }
    
            double ans=0;
            for(int i=1;i<(1<<n);i++){
                double sp=0;
                int cnt=0;
                for(int j=0;j<n;j++){
                    if(i&(1<<j)){
                        sp+=pro[j];
                        cnt++;
                    }
                }
                if(cnt%2) ans+=1.0/sp;
                else ans-=1.0/sp;
            }
    
            prf("%.5lf
    ",ans);
        }
        return 0;
    }
    
    //end-----------------------------------------------------------------------
  • 相关阅读:
    sql server profiler 对TextData进行过滤
    简单账表"小计"无法正常显示
    从字符串转换日期和/或时间时,转换失败。
    [转载]Java中的final与static的区别
    POI Excel导出样式设置
    [转载]poi 设置Region后单元格边框不起作用
    [转载]将java程序编译成独立运行的exe文件
    Java 线程安全问题—synchronized锁机制
    彻底理解ThreadLocal
    ThreadLocal封装Connection,实现同一线程共享资源
  • 原文地址:https://www.cnblogs.com/fenice/p/5973410.html
Copyright © 2011-2022 走看看