[SHOI2002]百事世界杯之旅

题目:“……在2002年6月之前购买的百事任何饮料的瓶盖上都会有一个百事球星的名字。只要凑齐所有百事球星的名字,就可参加百事世界杯之旅的抽奖活动,获得球星背包,随声听,更克赴日韩观看世界杯。还不赶快行动!”

你关上电视,心想:假设有n个不同的球星名字,每个名字出现的概率相同,平均需要买几瓶饮料才能凑齐所有的名字呢?

输入\(n(2\le n\le33)\),以带分数or整数的形式输出购买的期望数。

\(f[i]\)代表集齐\(i\)个明星需要的瓶盖数量。我们很容易得到

\(\displaystyle f[i]=\frac{i-1}{n}f[i]+\frac{n-i+1}{n}f[i-1]+1\)

然后这个式子不清真,因为\(f[i]\)的递推式里有\(f[i]\)递推个蛋啊,所以对\(f[i]\)移项

\(\displaystyle \frac{n-i+1}{n}f[i]=\frac{n-i+1}{n}f[i-1]+1\)

然后再搞搞

\(\displaystyle f[i]=f[i-1]+\frac{n}{n-i+1}\)

行了,这是一个递推式的形式,完美。。。。。

所以\(\displaystyle f[n]=\sum_{i=1}^n\frac{n}{n-i+1}=\sum_{i=1}^n\frac{n}{i}\)

行了,这就完美了。。。

然后呢我们就给他加加加哎哎哎家家爱阿基爱家啊啊

自己写一个分数的结构体捣鼓就行了

最后输出的时候,为了安全我多写了点,如代码:

如果这个代码没有成功地高亮显示,说明你在浏览某LJ网站,请自觉的点我。拒绝lj网站从我做起

#include <bits/stdc++.h>
using namespace std;
#define int long long

int getlen(long long x, bool mode)
{
    if(mode == 1 && x == 0)
        return 1;
    int ans = 0;
    while (x > 0)
    {
        ans++;
        x/= 10;
    }
    
    return ans;
}

struct fraction
{
    long long son, mother;
    fraction(int son = 0, int mother = 1) : son(son), mother(mother){}
    void redution(){int g = __gcd(mother, son);mother /= g;son /= g;}
    
    void print()
    {
        redution();
        long long div = son / mother;
        long long rest = son % mother;
        if (rest == 0)
        {
            printf("%lld\n", div);
            return;
        }
        int len = getlen(div, 0);
        int len1 = getlen(rest, 1);
        int len2 = getlen(mother, 1);
        int len3 = max(len1, len2);
        for (int i = 1; i <= len; i++)
            putchar(' ');
        printf("%lld\n", rest);
        if (div > 0)
            printf("%lld", div);
        for (int i = 1; i <= len3; i++)
            putchar('-');
        printf("\n");
        for (int i = 1; i <= len; i++)
            putchar(' ');
        printf("%lld\n", mother);
    }
    
}; 

fraction operator+(const fraction &a, const fraction &b)
{
    fraction ans(a.son * b.mother + a.mother * b.son, a.mother * b.mother);
    ans.redution();
    return ans;
}



signed main()
{
    int n; 
    scanf("%lld", &n);
    fraction ans;
    for (int i = 1; i <= n; i++)
    {
        fraction tmp(n, i);
        ans = ans + tmp;
    }
    ans.print();
    return 0;
}

转载于:https://www.cnblogs.com/oier/p/9640793.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值