HDU 4336 Card Collector:状压 + 期望dp

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4336

题意:

  有n种卡片(n <= 20)。

  对于每一包方便面,里面有卡片i的概率为p[i],可以没有卡片。

  问你集齐n种卡片所买方便面数量的期望。

题解:

  状态压缩。

  第i位表示手上有没有卡片i。

  表示状态:

    dp[state] = expectation

    (卡片状态为state时,要集齐卡片还要买的方便面数的期望)

  找出答案:

    ans = dp[0]

    刚开始一张卡片都没有。

  如何转移:

    now: dp[state]

    对于卡片i,如果手上已经有了i,则方便面里有i等价于面里什么都没有。

    所以子期望共两种:

      (1)拿到一张还没有的卡片i。

      (2)拿到垃圾2333。

    dp[state] = sigma( dp[state|(1<<i)] * p[i] ) + dp[state] * P(useless) + 1

    P(useless)为拿到垃圾的概率。

    设tot = sigma(p[i])

    P(useless) = 1 - tot

    原式移项后:

      dp[state] = ( sigma( dp[state|(1<<i)] * p[i] ) + 1 ) / tot

  边界条件:

    dp[(1<<n)-1] = 0

    已经集齐,不用再买。

AC Code:

 1 // state expression:
 2 // dp[state] = expectation
 3 // state: state of present cards
 4 //
 5 // find the answer:
 6 // ans = dp[0]
 7 //
 8 // transferring:
 9 // now: dp[state]
10 // dp[state] = sigma( dp[state|(1<<i)] * p[i] ) + dp[state] * P(useless) + 1
11 // i: not been collected
12 // dp[state] = ( sigma( dp[state|(1<<i)] * p[i] ) + 1 ) / (1 - P(useless))
13 // dp[state] = ( sigma( dp[state|(1<<i)] * p[i] ) + 1 ) / tot
14 //
15 // boundary:
16 // dp[(1<<n)-1] = 0
17 #include <iostream>
18 #include <stdio.h>
19 #include <string.h>
20 #define MAX_N 25
21 #define MAX_S ((1<<20)+5)
22 
23 using namespace std;
24 
25 int n;
26 double p[MAX_N];
27 double dp[MAX_S];
28 
29 void read()
30 {
31     for(int i=0;i<n;i++)
32     {
33         cin>>p[i];
34     }
35 }
36 
37 void solve()
38 {
39     memset(dp,0,sizeof(dp));
40     for(int state=(1<<n)-2;state>=0;state--)
41     {
42         double tot=0;
43         for(int i=0;i<n;i++)
44         {
45             if(!((state>>i)&1))
46             {
47                 dp[state]+=dp[state|(1<<i)]*p[i];
48                 tot+=p[i];
49             }
50         }
51         dp[state]=(dp[state]+1.0)/tot;
52     }
53 }
54 
55 void print()
56 {
57     printf("%.9f
",dp[0]);
58 }
59 
60 int main()
61 {
62     while(cin>>n)
63     {
64         read();
65         solve();
66         print();
67     }
68 }
原文地址:https://www.cnblogs.com/Leohh/p/7578131.html