题目:“……在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 longint 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;
}