对于n种不同的coupons,每次得到每种coupons的概率相同。为得到所有的coupons的期望
当已经得到了k种coupons时,得到另外一种的概率是
所以每一步的期望是
总的期望是
接下来只需要模拟分数计算即可
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <string.h>
#include <cstdlib>
#include <algorithm>
using namespace std;
typedef long long ll;
int cheak(ll x)
{
int res = 0;
while (x)
{
res++;
x /= 10;
}
return res;
}
ll gcd(ll x, ll y)
{
return y == 0 ? x : gcd(y, x%y);
}
ll lcm(ll x, ll y)
{
return x / gcd(x, y)*y;
}
ll zs[70], fz[70], fm[70];
int main()
{
fz[0] = 0;
fm[0] = 1;
zs[0] = 0;
for (ll i = 1; i <= 66; i++)
{
ll llcm = lcm(fm[i-1], i);
fz[i] = fz[i - 1] * (llcm / fm[i - 1]) + llcm / i;
fm[i] = llcm;
zs[i] = zs[i - 1] + fz[i] / fm[i];
fz[i] %= fm[i];
ll ggcd = gcd(fz[i], fm[i]);
fz[i] /= ggcd, fm[i] /= ggcd;
}
ll n;
while (scanf("%lld", &n) != EOF)
{
ll ans = n;
ans *= zs[n];
ll ggcd = gcd(n, fm[n]);
ll up = fz[n], down = fm[n];
n /= ggcd;
down /= ggcd;
up *= n;
ans += up / down;
up %= down;
if (up == 0)
{
printf("%lld\n", ans);
}
else
{
int kk = cheak(ans);
int maxx = max(cheak(up), cheak(down));
for (int i = 0; i <= kk; i++)printf(" ");
printf("%lld\n", up);
printf("%lld ", ans);
for (int i = 0; i < maxx; i++)printf("-");
printf("\n");
for (int i = 0; i <= kk; i++)printf(" ");
printf("%lld\n", down);
}
}
}