P1291 [SHOI2002] 百事世界杯之旅
设现在已经买到 \(m\) 个人的,一共有 \(n\) 个人。
第一瓶买到新人的概率 $ = \frac{n - m}{n}$
第二瓶买到新人的概率 $ = \frac{m}{n} \times \frac{n - m}{n}$,前两瓶买到新人的概率 $ = \frac{n - m}{n} + \frac{m}{n} \times \frac{n - m}{n} = \frac{n - m}{n} (1 + \frac{m}{n})$
以此类推,第 \(k\) 瓶买到新人的期望 \(E = \frac{n - m}{n} [1 + 2\frac{m}{n} + 3(\frac{m}{n})^2 + \dots + k(\frac{m}{n})^{k - 1}]\)
接下来开始漫长的推导:
\[\frac{m}{n} E = \frac{n - m}{n} [\frac{m}{n} + 2(\frac{m}{n})^2 + 3(\frac{m}{n})^3 + \dots + k(\frac{m}{n})^k]
\\
(1 - \frac{m}{n}) E = \frac{n - m}{n} E = \frac{n - m}{n} [1 + \frac{m}{n} + (\frac{m}{n})^2 + (\frac{m}{n})^3 + \dots + k(\frac{m}{n})^k]
\\
E = 1 + \frac{m}{n} + (\frac{m}{n})^2 + (\frac{m}{n})^3 + \dots + (k - 1)(\frac{m}{n})^{k - 1} + k(\frac{m}{n})^k
\]
推到这,除掉最后的一项 \(k(\frac{m}{n})^k\),\(E\) 就是一个完美的等比数列。
别忘了,\(k(\frac{m}{n})^k\) 是无限趋近于 \(0\) 的,而 \(k\) 又是无穷大的,因此,这一项就等于 \(0\)。
\[E = \frac{m}{n} + (\frac{m}{n})^2 + (\frac{m}{n})^3 + \dots + (k - 1)(\frac{m}{n})^{k - 1}
\]
再根据等比数列求和公式可得:
\[S_E = 1 + \frac{m}{n} \times \frac{1 - (\frac{m}{n})^{k - 1}}{1 - \frac{m}{n}} = 1 + \frac{m}{n} \times \frac{1}{\frac{n - m}{n}} = 1 + \frac{m}{n} \times \frac{n}{n - m} = 1 + \frac{m}{n - m} = \frac{n}{n - m}
\]
这里因为 \(k\) 是无穷大的,那么 \(k - 1\) 也是无穷大的,因此 \((\frac{m}{n})^{k - 1} = 0\),可忽略。
设 \(f_i\) 表示买第 \(i\) 个人(已经买了 \(i - 1\) 个人)的期望值,由我们刚才推出来的结论,不难得出:
\[f_i = f_{i - 1} + \frac{n}{n - m}
\]
在递推的过程中维护分子分母,最后再处理输出就好啦~
\(Code:\)
#include <bits/stdc++.h>
#define MAXN 40
using namespace std;
typedef long long ll;
int n;
template<typename _T>
inline void read(_T &_x) {
_x = 0;
_T _f = 1;
char _ch = getchar();
while (_ch < '0' || '9' < _ch) {
if (_ch == '-') _f = -1;
_ch = getchar();
}
while ('0' <= _ch && _ch <= '9') {
_x = (_x << 3) + (_x << 1) + (_ch & 15);
_ch = getchar();
}
_x *= _f;
}
template<typename _T>
inline void write(_T _x) {
if (_x < 0) {
putchar('-');
_x = -_x;
}
if (_x > 9) write(_x / 10);
putchar('0' + _x % 10);
}
int count(ll x) {
int res = 0;
while (x) {
res++;
x /= 10;
}
return res;
}
int main() {
read(n);
ll a = n, b = n;
for (int i = 2; i <= n; i++) {
a = a * (n - i + 1) + n * b;
b *= (n - i + 1);
int gcd = __gcd(a, b);
a /= gcd, b /= gcd;
}
ll z = a / b;
a %= b;
if (!a) {
write(z);
return 0;
}
int cz = count(z), cb = count(b);
for (int i = 1; i <= cz; i++) putchar(' '); write(a), putchar('\n');
write(z); for (int i = 1; i <= cb; i++) putchar('-'); putchar('\n');
for (int i = 1; i <= cz; i++) putchar(' '); write(b);
return 0;
}

浙公网安备 33010602011771号