hdu4336Card Collector 概率dp+状态压缩

//给n个卡片每次出现的概率,求全部卡片都出现的须要抽的次数的期望
//dp[i]表示在状态的情况下到全部的卡片都出现的期望
//dp[i] = 1 + p1*dp[i] + ${p2[j]*dp[i]} + ${p3[k]*dp[i^(1<<k)]}
//$表示求和。p1表示没有出现卡片的概率 , p2[j]表示出现的卡片是当前状态已经出现的状态
//p3表示出现的卡片当前状态没有
//整理的dp[i] = (1 +  ${p3[k]*dp[i^(1<<k)])/${p3[k]}
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std ;
const int maxn = 1 << 21 ;
double dp[maxn] ;
double p[21] ;
int main()
{
    int  n ;
    while(~scanf("%d" , &n))
    {
        for(int i = 0;i < n;i++)
        scanf("%lf" , &p[i]) ;
        dp[0] = 0 ;
        int lim = (1<<(n)) ;
        for(int i = 1;i < lim;i++)
        {
              double sum = 0;
              dp[i] = 1;
              for(int j = 0;j < n;j++)
              {
                  if((i&(1<<j)))
                  {
                      dp[i] += dp[i^(1<<j)]*p[j] ;
                      sum+=p[j];
                  }
              }
              dp[i]/=sum ;
        }
        printf("%lf " , dp[lim - 1]) ;
    }
}





原文地址:https://www.cnblogs.com/brucemengbm/p/6971131.html