题意:有n种卡片,每袋零食里面有p[i]的概率含有卡片i,最多含有一张卡片,也可能不含卡片。求要收集齐n张卡片所需要买的零食袋数的期望。(1 <= n <= 20)
解法:状压DP+概率DP。设d[i]表示含有卡片的状态为i时所需的期望零食袋数。d[i] = Σ((d[i] + 1)*p[j]) + Σ((d[i|(1<<k)]+1)*p[k]),其中j表示i状态下已经拥有的卡片,k表示没有的。
tag:状压DP,概率DP

1 /* 2 * Author: Plumrain 3 * Created Time: 2013-11-16 21:24 4 * File Name: DP-HDU-4336.cpp 5 */ 6 #include <iostream> 7 #include <cstdio> 8 #include <cstring> 9 10 using namespace std; 11 12 #define CLR(x) memset(x, 0, sizeof(x)) 13 14 double d[1<<20], p[100]; 15 16 int main() 17 { 18 int n; 19 while (scanf ("%d", &n) != EOF){ 20 double px = 1.0; 21 for (int i = 0; i < n; ++ i){ 22 scanf ("%lf", &p[i]); 23 px -= p[i]; 24 } 25 26 CLR (d); 27 for (int i = (1<<n) - 2; i >= 0; -- i){ 28 double tmp = px; 29 for (int j = 0; j < n; ++ j){ 30 if (!(i & (1<<j))) 31 d[i] += p[j] * (1 + d[i|(1<<j)]); 32 else 33 tmp += p[j]; 34 } 35 d[i] = (d[i] + tmp) / (1 - tmp); 36 } 37 printf ("%.6f ", d[0]); 38 } 39 return 0; 40 }