Uva 10288 Coupons (概率dp)

大题题意:

一共有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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值