UVA-10288 Coupons 数学期望
UVA-10288 Coupons 数学期望
题意
每张彩票上有一个漂亮图案,图案一共n种,如果你集齐了这n种图案就可以召唤神龙兑换大奖。
现在请问,在理想(平均)情况下,你买多少张彩票才能获得大奖的?
\[n \leq 33
\]
输入输出采用分数形式
分析
假设当前已经得到了\(k\)种图案,那么得到新的图案的概率是\(\frac{n - k}{n}\)
期望次数就是\(\frac{n}{n-k}\)
令\(E(i)\)表示从\(i- 1\)种到\(i\)种的期望
根据期望的线性性质
\[EX = \sum E(i)\\
= \sum \frac{n}{n-i}\\
=n \sum \frac{1}{i}
\]
代码
class Rat {
public:
ll a;
ll b;
Rat(ll x, ll y) { a = x, b = y; }
void add(Rat r) {
a = a * r.b + b * r.a;
b = b * r.b;
ll tmp = a;
a /= gcd(a, b);
b /= gcd(tmp, b);
}
};
int getlen(ll x) {
int cnt = 0;
while (x) x /= 10, cnt++;
return cnt;
}
void out(Rat r) {
ll n = r.a / r.b;
ll s = r.a % r.b;
if (s == 0) printf("%lld\n", n);
else if (n == 1) {
int len1 = getlen(s);
int len2 = getlen(r.b);
printf("%lld\n", s);
int tmp = max(len2, len1);
while (tmp--) printf("-");
printf("%lld\n", r.b);
}
else {
int len1 = getlen(n);
len1++;
int l1 = len1;
int len2 = getlen(r.b);
int len3 = getlen(s);
len2++;
len3++;
while (len1--) printf(" "); printf("%lld\n", s);
printf("%lld", n); printf(" ");
int tmp = max(len2, len3);
tmp--;
while (tmp--) printf("-");
puts("");
while (l1--) printf(" "); printf("%lld", r.b);
puts("");
}
}
int main() {
int n;
while (~scanf("%d", &n)) {
Rat r(1ll , 1ll);
for (int i = 2; i <= n; i++) r.add(Rat(1, i));
r.a *= n;
ll x = r.a;
ll y = r.b;
r.a /= gcd(x, y);
r.b /= gcd(x, y);
out(r);
}
}