Uva 10288 Coupons (概率dp)

来源:互联网 发布:c语言捕鱼 编辑:程序博客网 时间:2024/04/30 13:50

大题题意:

一共有n 种不同的优惠券,每次得到每种优惠券的概率相同。问期望多少次可以得到所有n 种的优惠券,以带分数的形式输出!

思路:

这个题 用dp思想比较好理解一些!

令dp[i]表示已经得到了 i种优惠券!

那么dp[i]的转移可以来自i-1种的情况得到一种新的种类!

也可以来自i种 得到了一种原来的种类!

在+1即可!

即:

dp[i] = dp[i-1] * (n-i+1)/n + dp[i] * (i-1)/n + 1;

有一个小规律,即加1的前面系数的和一定是1。

这种套路比较常见了,在一些概率dp中!

详细见代码:

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;typedef long long ll;ll gcd(ll a,ll b){    return !b ? a : gcd(b,a%b);}struct Fra{    ll fz;    ll fm;    Fra(){fz = fm = 1;}    Fra(ll fz,ll fm):fz(fz),fm(fm){}    Fra operator + (Fra o)  {        Fra ans = Fra();        ll t1 = fz*o.fm+fm*o.fz;        ll t2 = fm*o.fm;        ll g = gcd(t1,t2);        t1/=g; t2/=g;        ans.fz = t1;        ans.fm = t2;        return ans;    }}dp[40];int bit(ll n){    int a = 0;    while(n){        n/=10;        a++;    }    return a;}int main(){    int n;    dp[0].fz = 0;    dp[0].fm = 1;    while(~scanf("%d",&n)){        for (int i = 1; i <= n; ++i){            Fra tmp = Fra((ll)n,(ll)n-i+1);            dp[i] = dp[i-1] + tmp;        }        ll fz = dp[n].fz;        ll fm = dp[n].fm;        if (fz % fm == 0){            printf("%lld\n",fz/fm);        }        else {            ll z = fz/fm;            fz %= fm;            ll g = gcd(fz,fm);            fz /= g; fm/=g;            int bz = bit(z)+1;            for (int i = 0; i < bz; ++i)printf(" ");            printf("%lld\n",fz);            printf("%lld ",z);            int Max = max(bit(fz),bit(fm));            for (int i = 0; i < Max; ++i)printf("-");            puts("");            for (int i = 0; i < bz; ++i)printf(" ");            printf("%lld\n",fm);        }    }    return 0;}



0 0
原创粉丝点击