hdu4336 Card Collector min-max容斥

版权声明:虽然是个蒟蒻但是转载还是要说一声的哟 https://blog.csdn.net/jpwang8/article/details/85639169

Description


给n个包,每个包有选中的概率 P i P_i i = 1 n P i 1 \sum\limits_{i=1}^n P_i\le 1 ,每次随机选一个包,问拿完n个包的期望次数
n 20 n\le 20

Solution


有一个叫min-max容斥的东西,我只听过跟这个类似的min-max卷积
min ( S ) \min \left(S\right) 表示集合S内的最小值,同理 max ( S ) \max\left(S\right) 为集合内最大值
我们有恒等式 max ( S ) = T S ( 1 ) T + 1 min ( T ) \max\left(S\right)=\sum\limits_{T\subset S}{{\left(-1\right)}^{|T|+1}\cdot\min\left(T\right)}

什么意思呢?对于一些最大值比较难求但是最小值很好求的题目可以考虑这个转化,并且如果套在期望里面也是满足的

为什么这个是对的呢?我们考虑第i大数字前的系数,也就是 j = 1 n i + 1 ( n i j 1 ) ( 1 ) j + 1 = [ n = i ] \sum\limits_{j=1}^{n-i+1}{\binom{n-i}{j-1}\cdot(-1)^{j+1}}=[n=i] ,于是得证

在这题就是我们枚举所有包的子集,考虑已知集合 S S 怎么求 min ( S ) \min\left(S\right) ,也即是集合中最早出现数字出现的期望,也就是集合中出现至少一个数字的期望。记 P = i S P i P'=\sum\limits_{i\in S}P_i ,期望的计算实际上就是 i = 1 i P ( 1 P ) i 1 \sum\limits_{i=1}^{\infin}{i\cdot P'{\left(1-P'\right)}^{i-1}} ,错位相减求和然后高阶无穷小近似掉就没了

当然一个比较naive的做法是状压dp,这个是 O ( 2 n n ) O(2^n *n)

Code


#include <stdio.h>
#include <algorithm>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)

typedef double db;
const int N=20005;

db p[N],ans;

int n;

void dfs(int dep,db S,db T) {
	if (dep==n+1) return (void) ((S>1e-9)?(ans+=T/S):0);
	dfs(dep+1,S+p[dep],-T);
	dfs(dep+1,S,T);
}

int main(void) {
	for (;~scanf("%d",&n);ans=0) {
		rep(i,1,n) scanf("%lf",&p[i]);
		dfs(1,0,-1);
		printf("%.4lf\n", ans);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/jpwang8/article/details/85639169