• hdu4336 Card Collector 【最值反演】


    题目链接

    hdu4336

    题解

    最值反演

    也叫做(min-max)容斥,在计算期望时有奇效

    [max{S} = sumlimits_{T in S} (-1)^{|T| + 1}min{T} ]

    证明:
    (S = {a_i}),其中对于(i < j)(a_i < a_j)
    那么我们计算每一个(a_i)的贡献,有

    [egin{aligned} sumlimits_{T in S} (-1)^{|T| + 1}min{T} &= sumlimits_{i = 1}^{n}a_isumlimits_{j = 0}^{n - i}(-1)^{j}{n - i choose j}\ &= sumlimits_{i = 1}^{n}a_i[n - i = 0]\ &= sumlimits_{i = 1}^{n}a_i[n = i]\ &= a_n\ &= max{S} end{aligned} ]

    证毕

    对于此题,我们想要求出所有卡片集合(S)中最晚出现的卡片的期望,就转化为计算(S)的所有子集中最早出现的期望
    对于一个集合(T),显然出现一张卡片的期望为

    [frac{1}{sumlimits_{i in T}p_i} ]

    枚举子集计算即可
    复杂度(O(2^n))

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<map>
    #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    #define mp(a,b) make_pair<int,int>(a,b)
    #define cls(s) memset(s,0,sizeof(s))
    #define cp pair<int,int>
    #define LL long long int
    using namespace std;
    const int maxn = 25,maxm = 100005,INF = 1000000000;
    double p[maxn],ans;
    int n;
    int main(){
    	while (~scanf("%d",&n)){
    		REP(i,n) scanf("%lf",&p[i]);
    		int maxv = (1 << n) - 1; ans = 0;
    		for (int s = 1; s <= maxv; s++){
    			int cnt = 0; double tmp = 0;
    			for (int e = s,j = 1; e; e >>= 1,j++)
    				if (e & 1) cnt++,tmp += p[j];
    			ans += (cnt & 1) ? 1 / tmp : -1 / tmp;
    		}
    		printf("%.8lf
    ",ans);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    CountDownLatch原理分析
    Maven項目打包報錯:Plugin execution not covered by lifecycle configuration
    Java实现编辑距离算法
    MQ的深入理解
    关于HashMap
    JVM基础详解
    Java实现Mysql的 substring_index 函数功能
    Kettle发送邮件
    Kettle实现从数据库中提取数据到Excel
    bzoj1596[Usaco2008 Jan]电话网络*
  • 原文地址:https://www.cnblogs.com/Mychael/p/9230174.html
Copyright © 2020-2023  润新知