题目描述
黑箱子里面有N种不同类型的彩球,每次你只能从箱子摸一个彩球出来,第i种彩球出现的频率是p[i]。问要摸多少次才能凑齐所有类型的彩球,输出期望值。
输入输出格式
输入格式
多组测试数据。
第一行,一个整数G,表示有G组测试数据。1 <= G <= 3
每组测试数据格式如下:
第一行,一个整数N。1 <= N <= 20
第二行,N个整数,第i个整数是p[i], 1 <=p[i]<=1000。
输出格式
共G行,每行一个实数,与误差不超过0.00001
输入输出样例
输入样例
3
1
1
2
2 2
3
1 1 100
输出样例
1.0
3.0
153.00019801980199
题解
二进制状压之后直接dp即可。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include <iostream> #include <cstdio> #define MAX_N (20 + 5) #define lowbit(x) ((x) & -(x)) using namespace std; int G; int n; int a[MAX_N]; int tab[1 << 20]; int sum, lim; double dp[1 << 20]; int main() { scanf("%d", &G); for(register int i = 1; i <= 20; ++i) { tab[1 << i - 1] = i; } int tmp; double p; while(G--) { scanf("%d", &n); sum = 0; for(register int i = 1; i <= n; ++i) { scanf("%d", a + i); sum += a[i]; } lim = (1 << n) - 1; dp[lim] = 0; for(register int i = lim - 1; i >= 0; --i) { dp[i] = 1; tmp = i; p = 0; for(register int j = 1; j <= lim; j <<= 1) { if(j == lowbit(tmp)) { p += a[tab[j]]; tmp -= j; continue; } dp[i] += dp[i + j] * a[tab[j]] / sum; } p /= sum; dp[i] /= (1 - p); } printf("%lf", dp[0]); } return 0; }