狀壓dp入門,HDU 4336 Card Collector:狀壓 + 期望dp

 2023-12-25 阅读 36 评论 0

摘要:題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=4336 題意:   有n種卡片(n <= 20)。   對于每一包方便面,里面有卡片i的概率為p[i],可以沒有卡片。   問你集齊n種卡片所買方便面數量的期望。 ? 題解:   狀態壓縮

題目鏈接: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\n",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

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/1/195000.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息