期望dp-hdu-4336-Card Collector
阿新 • • 發佈:2019-01-24
題目連結:
題目大意:
有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; }