zoukankan      html  css  js  c++  java
  • HDU 4336 Card Collector(状压 + 概率DP 期望)题解

    题意:每包干脆面可能开出卡或者什么都没有,一共n种卡,每种卡每包爆率pi,问收齐n种卡的期望

    思路:期望求解公式为:$E(x) = sum_{i=1}^{k}pi * xi + (1 - sum_{i = 1}^{k}pi) * [1 + E(x)]$,即能转换到x情况的期望+x情况原地踏步的期望。

    因为n比较小,我们可以直接状压来表示dp[x]为x状态时集齐的期望。那么显然dp[111111111] = 0。然后我们状态反向求解。最终答案为dp[0]。

    然后来看期望的求解:$E(x) = sum_{i = 1}^{k}pi * [1 + E(xi)] + (1 - sum_{i = 1}^{k}pi) * [1 + E(x)]$,E(xi)是E(x)某一位0变成1后的期望。

    化简后:$E(x) = (sum_{i = 1}^{k}pi * E(xi) + 1) / sum_{i = 1}^{k}pi$

    题解

    代码:

    #include<set>
    #include<map>
    #include<cmath>
    #include<queue>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include <iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int maxn = 20 + 5;
    const int M = maxn * 30;
    const ull seed = 131;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1e4 + 7;
    double dp[1 << maxn];
    double p[maxn];
    int main(){
        int n;
        while(~scanf("%d", &n)){
    //        for(int i = 0; i < (1 << n); i++) dp[i] = 0;
            for(int i = 0; i < n; i++){
                scanf("%lf", &p[i]);
            }
            dp[(1 << n) - 1] = 0;
            for(int i = (1 << n) - 2; i >= 0; i--){
                double sump = 0, sumpe = 0;
                for(int j = 0; j < n; j++){
                    if(!(i & (1 << j))){
                        sump += p[j];
                        sumpe += p[j] * dp[i | (1 << j)];
                    }
                }
                dp[i] = (sumpe + 1) / sump;
            }
            printf("%.6f
    ", dp[0]);
        }
        return 0;
    }
  • 相关阅读:
    扒几个 3D 模型备用
    向 3D 世界迈出一小步
    为什么说使用 Linux 系统学习 OpenGL 更方便
    Windows 下的 Linux环境
    windows git 的扩展用法——其他linux命令
    Linux 环境变量
    powershell(或者windows terminal)中使用git
    QT无边框窗体——拦截windows消息实现
    QT工具——开发技巧与其他工具
    QT工具——国际化工具
  • 原文地址:https://www.cnblogs.com/KirinSB/p/10987317.html
Copyright © 2011-2022 走看看