UVA 10288 - courpons (mathematical expectation + score calculation)

Posted by spikeon on Thu, 02 Jan 2020 19:33:03 +0100

Title Link https://cn.vjudge.net/problem/UVA-10288

[title]
There are n different lotteries. If you collect all the lotteries, you can exchange them for the grand prize (n < = 33). The kinds of lotteries you buy are random. How many lotteries do you need to buy to exchange the grand prize on average? Answer by score

[thinking]
There are already kk kinds of lotteries, let s=kns=kn, then suppose that the number of times needed to buy a new lottery is tt, and the corresponding probability is St − 1 (1 − s)st − 1 (1 − s), so the average number of times needed is

C(k)=∑t=1+∞st−1(1−s)t=(1−s)∑t=1+∞st−1tC(k)=∑t=1+∞st−1(1−s)t=(1−s)∑t=1+∞st−1t
Then use the offset subtraction method to set
F(t)=∑t=1+∞st−1t=1+2s+3s2+4s3+......F(t)=∑t=1+∞st−1t=1+2s+3s2+4s3+......
sF(t)=∑t=1+∞stt=s+2s2+3s3+4s4+......sF(t)=∑t=1+∞stt=s+2s2+3s3+4s4+......
be
F(t)−sF(t)=1+s+s2+s3+...=limn→+∞1−sn+11−s=11−sF(t)−sF(t)=1+s+s2+s3+...=limn→+∞1−sn+11−s=11−s
therefore
F(t)=1(1−s)2F(t)=1(1−s)2
C(k)=11−s=nn−kC(k)=11−s=nn−k
The final result is
∑k=0n−1C(k)=n∑k=0n−11n−k∑k=0n−1C(k)=n∑k=0n−11n−k

The results need to be expressed in fractions. Here is a board for fraction calculation

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

long long __gcd(long long a,long long b){
    if(b==0) return a;
    return __gcd(b,a%b);
}

struct fraction {
    long long numerator;//molecule
    long long denominator;//Denominator
    fraction() {
        numerator = 0;
        denominator = 1;
    }
    fraction(long long num) {
        numerator = num;
        denominator = 1;
    }
    fraction(long long a, long long b) {
        numerator = a;
        denominator = b;
        this->reduction();
    }

    void operator = (const long long num) {
        numerator = num;
        denominator = 1;
        this->reduction();
    }

    void operator = (const fraction &b) {
        numerator = b.numerator;
        denominator = b.denominator;
        this->reduction();
    }

    fraction operator + (const fraction &b) const {
        long long gcdnum = __gcd(denominator, b.denominator);
        fraction tmp = fraction(numerator*(b.denominator/gcdnum) + b.numerator*(denominator/gcdnum), denominator/gcdnum*b.denominator);
        tmp.reduction();
        return tmp;
    }

    fraction operator + (const int &b) const {
        return ((*this) + fraction(b));
    }

    fraction operator - (const fraction &b) const {
        return ((*this) + fraction(-b.numerator, b.denominator));
    }

    fraction operator - (const int &b) const {
        return ((*this) - fraction(b));
    }

    fraction operator * (const fraction &b) const {
        fraction tmp = fraction(numerator*b.numerator, denominator * b.denominator);
        tmp.reduction();
        return tmp;
    }

    fraction operator * (const int &b) const {
        return ((*this) * fraction(b));
    }

    fraction operator / (const fraction &b) const {
        return ((*this) * fraction(b.denominator, b.numerator));
    }

    void reduction() {
        if (numerator == 0) {
            denominator = 1;
            return;
        }
        long long gcdnum = __gcd(numerator, denominator);
        numerator /= gcdnum;
        denominator /= gcdnum;
    }
};

fraction a[50];

int main(){
    int n;
    while(scanf("%d",&n)==1){
        for(int i=1;i<=n;++i){
            a[i]=fraction(1,i);
        }
        for(int i=2;i<=n;++i){
            a[1]=a[1]+a[i];
        }
        a[1]=a[1]*n;
        long long x=a[1].numerator;
        long long y=a[1].denominator;
        if(y==1) printf("%lld\n",x);
        else{
            long long tmp=x/y,tmpy=y;
            int ctmp=0,cy=0;
            while(tmp){
                ++ctmp;
                tmp/=10;
            }
            while(tmpy){
                ++cy;
                tmpy/=10;
            }
            for(int i=0;i<=ctmp;++i) putchar(' ');
            printf("%lld\n",x%y);
            printf("%lld ",x/y);
            for(int i=0;i<cy;++i) putchar('-');
            puts("");
            for(int i=0;i<=ctmp;++i) putchar(' ');
            printf("%lld\n",y);
        }
    }
    return 0;
}