问题
分析
已有k个图案, p = k / n , q = 1 − p p=k/n,q=1-p p=k/n,q=1−p,现在要拿到一个新的,需要t次实验的概率是 p t − 1 ∗ q p^{t-1}*q pt−1∗q,符合几何分布,几何分布的期望是 1 / q = 1 / ( 1 − p ) = n / ( n − k ) 1/q=1/(1-p)=n/(n-k) 1/q=1/(1−p)=n/(n−k),也就是说,已有k个团,平均拿 n / ( n − k ) n/(n-k) n/(n−k)次就可以多拿一个,所以 S = ∑ i = 0 n − 1 n n − k S=\sum_{i=0}^{n-1}\frac{n}{n-k} S=∑i=0n−1n−kn
#include <cstring>
#include <cstdio>
#include <iostream>
using namespace std;
typedef long long ll;
const int maxn=34;
struct ANS{
//a c/b
ll a,b,c;
int l1,l2;
ANS(ll a=0,ll b=0,ll c=0,int l1=0,int l2=0):a(a),b(b),c(c),l1(l1),l2(l2){}
}ans[maxn];
int n;
inline ll gcd(ll a,ll b){
return (b==0)?a:gcd(b,a%b);
}
inline ll lcm(ll a,ll b){
return a/gcd(a,b)*b;
}
void init(){
ll t;
//1+1/2+1/3+...+1/i的累加,如果大于1,就化为整数
for(int i=1;i<maxn;++i){
if(ans[i-1].c!=0){
t=lcm(ans[i-1].b,i);;
ans[i].c=t/ans[i-1].b*ans[i-1].c+t/i;
ans[i].b=t;
t=gcd(ans[i].b,ans[i].c);
ans[i].b/=t;
ans[i].c/=t;
}else {
ans[i].c=1;
ans[i].b=i;
}
ans[i].a=ans[i-1].a+ans[i].c/ans[i].b;
ans[i].c=ans[i].c%ans[i].b;
}
//乘以i
for(int i=1;i<maxn;++i){
ans[i].a*=i;
ans[i].c*=i;
ans[i].a+=ans[i].c/ans[i].b;
ans[i].c=ans[i].c%ans[i].b;
t=gcd(ans[i].b,ans[i].c);
ans[i].b/=t;
ans[i].c/=t;
t=ans[i].a;
while(t){
t=t/10;
ans[i].l1++;
}
t=ans[i].b;
while(t){
t=t/10;
ans[i].l2++;
}
}
}
int main(void){
init();
while(cin>>n){
ANS temp=ans[n];
if(temp.c==0) printf("%lld\n",temp.a);
else {
for(int i=0;i<=temp.l1;++i) putchar(' ');
printf("%lld\n",temp.c);
printf("%lld",temp.a);
putchar(' ');
for(int i=0;i<temp.l2;++i) putchar('-');
printf("\n");
for(int i=0;i<=temp.l1;++i) putchar(' ');
printf("%lld\n",temp.b);
}
}
return 0;
}