UVA - 10288 Coupons

题形:概率DP

题意:收集齐n个不同的优惠卷的期望开箱次数。(开一次箱子会等概率的得到其中一张优惠卷)

思路:

期望递推法。

正常做就行。就是分数输出麻烦了点。

e[i] = i/n(e[i]+1) + (n-i)/n(e[i+1]+1)

然后移项,递推就行了。

代码:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define N 50 

struct fraction {
    long long numerator; // 分子
    long long 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;
    }
    void print() {
        if (denominator == 1) printf("%lld\n", numerator);
        else {
            long long num = numerator/denominator;
            long long tmp = num;
            int len = 0;
            while (tmp) {
                len++;
                tmp/=10;
            }

            for (int i = 0; i < len; i++) printf(" ");
            if (len != 0) printf(" ");
            printf("%lld\n",numerator%denominator);

            if (num != 0) printf("%lld ", num);
            tmp = denominator;
            while (tmp) {
                printf("-");
                tmp/=10;
            }
            puts("");

            for (int i = 0; i < len; i++) printf(" ");
            if (len != 0) printf(" ");
            printf("%lld\n",denominator);
        }
        //printf("%lld/%lld\n", numerator, denominator);
    }
};

fraction e[N];

int main() {
    int n;
    while (scanf("%d", &n) != EOF) {
        e[n] = 0;
        for (int i = n-1; i >= 0; i--) {
            e[i] = (fraction(i,n) + fraction(n-i,n)*(e[i+1]+1)) / fraction(n-i,n);
        }
        e[0].print();
    }
    return 0;
}

 

posted on 2014-03-07 16:15  ShineCheng  阅读(333)  评论(0编辑  收藏  举报

导航