• 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 }
  • 相关阅读:
    PAT 1037. 在霍格沃茨找零钱(20)
    PAT 1036. 跟奥巴马一起编程(15)
    Topcoder SRM633 DIV2 解题报告
    HDU 4565 So Easy! 矩阵快速幂 + 共轭数
    HDU 2256 Problem of Precision 矩阵快速幂 + 共轭数
    FZU 1683 纪念SlingShot 矩阵快速幂
    CodeForces 185A Plant 矩阵快速幂
    HDU 2604 Queuing 矩阵快速幂
    HDU 1575 Tr A 矩阵快速幂
    HDU 1757 A Simple Math Problem 矩阵快速幂
  • 原文地址:https://www.cnblogs.com/Leohh/p/7578131.html
Copyright © 2020-2023  润新知