期望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; }