UVa 10288

UVa 10288
题意:给你n个Conous,每个出现的概率相等,问你每次随机生成一个Conous,需要的次数的期望。
思路:令dp[i]代表还需要产出i个不同的未出现的Conous的期望次数,即前面的序列已经产出了n-i个
那么有dp[i]=(i/n)(1+dp[i-1])+(1-i/n)(1+dp[i])
i/n*dp[i]=1+i/n*dp[i-1]
dp[i]=n/i+dp[i-1]
dp[n]=sum(n/i) | i=1 to n
注意分数的运算就可以了

// author:latstars
// time:20161122 19:00
// 概率

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
using namespace std;
const int maxn=100;
typedef long long LL;
struct Fraction{
    LL numerator;
    LL denominator;
    LL integer;
    Fraction(){}
    Fraction(LL n,LL m,LL i)
    {
        integer=i;
        if(n>=m){
            integer=i+n/m;
            n-=n/m*m;
        }
        LL g=__gcd(m,n);
        m/=g;
        n/=g;
        numerator=n;
        denominator=m;

    }
};
Fraction operator + (const Fraction & A,const Fraction & B)
{
    LL a,b,c;
    a=A.integer+B.integer;
    b=c=0;
    c=A.denominator*B.denominator;
    b=A.numerator*B.denominator+B.numerator*A.denominator;
    if(b>=c){
        a+=b/c;
        b-=b/c*c;
    }
    LL g=__gcd(c,b);
    b/=g;c/=g;

    return Fraction(b,c,a);
}
int n;
void solve(void)
{
    Fraction ans(0,1,0);
    for(int i=1;i<=n;i++){
        Fraction f(1LL*n,1LL*i,0LL);
        ans=ans+f;
    }

    if(ans.numerator){
        int len1=0,len2=0,len3=0;
        LL a=ans.numerator,b=ans.denominator,c=ans.integer;
        while(a){
            len1++;
            a/=10;
        }
        while(b){
            len2++;
            b/=10;
        }
        while(c){
            len3++;
            c/=10;
        }
        int h=max(len1,len2),sp=len3+1;
        for(int i=1;i<=sp;i++)
            printf(" ");
        printf("%lld\n",ans.numerator);
        printf("%lld ",ans.integer);
        for(int i=1;i<=h;i++)
            printf("-");
        puts("");
        for(int i=1;i<=sp;i++)
            printf(" ");
        printf("%lld\n",ans.denominator);
    }
    else{
        printf("%lld\n",ans.integer);
    }
}
int main()
{

    while(scanf("%d",&n)!=EOF){
        solve();
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值