HDU-5985 Lucky Coins (概率)
题目链接:HDU-5985 Lucky Coins
题意
给出 n 种硬币,已知每种硬币的个数和抛掷后正面朝上的概率,每次将所有硬币抛掷,背面朝上的丢弃,直到只剩下一种硬币被称为幸运硬币,问每种硬币成为幸运硬币的概率。
思路
令 \(f[i][k]\) 表示第 \(i\) 种硬币第 \(k\) 轮之后全无剩下的概率,\(p_i\) 表示第 \(i\) 种硬币正面朝上的概率,\(n_i\) 表示第 \(i\) 种硬币的个数,则 \(f[i][k] = (1-p_i^k)^{n_i}\) 。
令 \(g[i][k]\) 表示第 \(i\) 种硬币第 \(k\) 轮之后至少还剩下一个的概率,显然 \(g[i][k] = 1-f[i][k]\) 。
令 \(ans[i]\) 表示第 \(i\) 种硬币成为幸运硬币的概率,则
\[ans[i] = \sum_{k=0}^\infty(g[i][k]-g[i][k+1])\prod_{j=1,j\ne i}^nf[j][k]
\]
后面的连乘表示除了第 \(i\) 种硬币外,其他的硬币在第 \(k\) 轮之后全无剩下的概率,\(g[i][k]-g[i][k+1]\) 表示第 \(i\) 种硬币在第 \(k\) 轮之后还有剩下,在第 \(k+1\) 轮之后全无剩下的概率,即恰好在第 \(k\) 轮之后成为幸运硬币的概率。如果没有减去 \(g[i][k+1]\) ,意义是在第 \(k\sim \infty\) 轮之后成为幸运硬币的概率,后面再算 \(k+1\sim \infty,k+2\sim \infty...\) 轮,会重复计算。
本题中给定的概率值在 0.4~0.6 之间,当硬币投掷次数很多时,几乎不会对后面的概率产生影响,所以选择能够不超时间空间的近似无穷大值作为 \(k\) 值的上界即可。
代码实现
#include <cstdio>
double f[11][1010];
double qpow(double a, int b) {
double res = 1;
while (b) {
if (b & 1) res = res * a;
b >>= 1;
a *= a;
}
return res;
}
int main() {
int T;
scanf("%d", &T);
while (T--) {
int n, ni, mxk = 1000;
double pi;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d %lf", &ni, &pi);
double pik = 1;
for (int k = 0; k < mxk; k++, pik *= pi) {
f[i][k] = qpow(1 - pik, ni);
}
}
for (int i = 0; i < n; i++) {
double ans = 0;
for (int k = 0; k < mxk - 1; k++) {
double tmp = 1;
for (int j = 0; j < n; j++) {
if (j == i) continue;
tmp *= f[j][k];
}
ans += (f[i][k+1] - f[i][k]) * tmp;
}
printf("%.6f%c", ans, " \n"[i==n-1]);
}
}
return 0;
}
作者:_kangkang
本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。