Description Coupons in cereal boxes are numbered 1 to n, and a set of
one of each is required for a prize (a cereal box, of course). With
one coupon per box, how many boxes on average are required to make a
complete set of n coupons?Input Input consists of a sequence of lines each containing a single
positive integer n, 1<=n<=22, giving the size of the set of coupons.Output For each input line, output the average number of boxes
required to collect the complete set of n coupons. If the answer is an
integer number, output the number. If the answer is not integer, then
output the integer part of the answer followed by a space and then by
the proper fraction in the format shown below. The fractional part
should be irreducible. There should be no trailing spaces in any line
of ouput.
假设已经有了k个优惠券,记s=k/n
再获得一个需要t次的概率为s^(t-1) * (1-s)
所以再获得一个的期望次数为(1-s) * (s^0+2 * s^1+3 * s^2+…)
记M=s^0+2 * s^1+3 * s^2+…
则s*M=s^1+2 * s^2+3 * s^3+…
(1-s) * M=s^0+s^1+s^2+…
记上式=T
s * T=s^1+s^2+s^3+…
(1-s) * T=s^0
T=1/(1-s)
即期望次数为n/(n-k)
所以总的期望次数为n(1/n+1/(n-1)+…+1/1)
注意分数运算。
#include<cstdio>
#include<cstring>
#define LL long long
struct num
{
LL a,b;
}n1,n2;
LL gcd(LL x,LL y)
{
return y?gcd(y,x%y):x;
}
LL lcm(LL x,LL y)
{
return x/gcd(x,y)*y;
}
void yf(num &nn)
{
LL x=gcd(nn.a,nn.b);
nn.a/=x;
nn.b/=x;
}
num operator + (const num n1,const num n2)
{
LL x=lcm(n1.b,n2.b);
num ans=(num){x/n1.b*n1.a+x/n2.b*n2.a,x};
yf(ans);
return ans;
}
void out(num x)
{
LL i,j,k,p,pp,q;
if (x.b==1)
{
printf("%lld\n",x.a);
return;
}
p=x.a/x.b;
while (p)
{
p/=10;
printf(" ");
}
printf(" ");
printf("%lld\n",x.a%x.b);
printf("%lld ",x.a/x.b);
q=x.b;
while (q)
{
q/=10;
printf("-");
}
printf("\n");
p=x.a/x.b;
while (p)
{
p/=10;
printf(" ");
}
printf(" ");
printf("%lld\n",x.b);
}
int main()
{
LL i,j,k,m,n,p,q,x,y,z;
num ans;
while (scanf("%lld",&n)==1)
{
ans=(num){1,1};
for (i=2;i<=n;i++)
ans=ans+(num){1,i};
ans.a*=n;
yf(ans);
out(ans);
}
}