期望dp-hdu-4336-Card Collector

题目链接:

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

题目大意:

有n种卡片,每包中至多有一种卡片,概率分别为p1,p2,...pn,可能有的没有卡片,求包数的期望,使得每种卡片都有。

解题思路:

由于n最多只有20,可以进行状态压缩。

dp[i]表示在状态i获得的卡片的情况下,得到最后结果所需的包数期望。

则dp[i]=no*(dp[i]+1)+∑pp[j]*(dp[i]+1)+∑pp[k]*(dp[i|(1<<k)]+1).

no:表示没有卡片的概率,∑pp[j]表示第j种卡片已经存在,∑pp[k]表示第j种卡片当前还没有。显然no+∑pp[j]+∑pp[k]=1,所以花间得dp[i]=1+(no+∑pp[j])*dp[i]+∑pp[k]*dp[i|(1<<k)]

dp[1<<n-1]=0递推求出dp[0]即可。

代码:

#include <iostream>
#include<cmath>
using namespace std;


double dp[1<<20],pp[25];

int main()
{
    int n;

    while(~scanf("%d",&n))
    {
        double no=0;

        for(int i=0;i<n;i++)
        {
            scanf("%lf",&pp[i]);
            no+=pp[i];
        }
        no=1-no;

        int lim=(1<<n)-1;
        dp[lim]=0;

        for(int i=lim-1;i>=0;i--)
        {
            dp[i]=1;
            double temp=0.0;
            for(int j=0;j<n;j++)
            {
                if(i&(1<<j))
                {
                    temp+=pp[j];
                    continue;
                }
                dp[i]+=dp[i|(1<<j)]*pp[j];
            }
            dp[i]/=(1-no-temp);
        }
        printf("%0.6f\n",dp[0]);
    }
    return 0;
}






 

你可能感兴趣的:(动态规划)