题目描述
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4336
题目大意:有(n)张卡牌,每秒有(p_i)的概率买到第(i)张卡,(sum p_ileqslant 1),问期望多少秒之后集齐所有卡。
Solution
(min-max)容斥板子题。
(min-max)容斥是说一个这样的式子:
[max{S}=sum_{Tsubseteq S}(-1)^{|T|+1}min{T}
]
这个式子在期望下成立,在这题(min{S})就表示(S)集合中第一张卡出现时间的期望,(max)就是最后一张的期望。
那么显然可以得到:
[min{S}=frac{1}{sum_{iin S}p_i}
]
然后范围比较小直接暴力算就好了。
时间复杂度(O(2^n))。
#include<bits/stdc++.h>
using namespace std;
void read(int &x) {
x=0;int f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
}
void print(int x) {
if(x<0) putchar('-'),x=-x;
if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('
');}
#define lf double
const int maxn = 2e5+10;
const lf eps = 1e-6;
int n;
lf p[maxn],ans;
void dfs(int now,lf sum,int f) {
if(now==n+1) return ans+=fabs(sum)<eps?0:(lf)f*1.0/sum,void();
dfs(now+1,sum+p[now],-f);
dfs(now+1,sum,f);
}
int main() {
while(scanf("%d",&n)!=EOF) {
for(int i=1;i<=n;i++) scanf("%lf",&p[i]);
dfs(1,0,-1);
printf("%lf
",ans);ans=0;
}
return 0;
}