[Fdu校赛2012]A Famous Game
题目描述 ¶
前置说明 ¶
需要使用到的一些东西:
-
贝叶斯公式:\(P(A|B)=\frac{P(AB)}{P(B)}\);
-
全概率公式:\(P(A)=\sum_{B\in S}P(B)P(A|B)\);
推导 ¶
然后就可以开始推式子,设 \(A\) 为我们后面拿出一个球的概率,\(B\) 为我们取出了 \(p\) 个球,其中有 \(q\) 个是红球的概率,那么:
\[\begin{aligned}{}
P(A|B)&=\frac{P(AB)}{P(B)} \\
&=\frac{\sum_{k=0}^nP(AB|N_k)P(N_k)}{\sum_{k=0}^nP(B|N_k)P(N_k)} \\
&=\frac{\sum_{k=0}^nP(A|B|N_k)P(B|N_k)P(N_k)}{\sum_{k=0}^nP(B|N_k)P(N_k)} \\
\end{aligned}
\]
对于最后的式子,易知:
\[P(A|B|N_k)=\frac{k-q}{n-p} \\
P(B|N_k)=\frac{{k\choose q}{n-k\choose p-q}}{{n\choose p}} \\
P(N_k)=\frac{1}{n+1}
\]
把这些我们全都知道的东西带进去,就会得到:
\[\begin{aligned}
(*)&=\frac{\sum_{k=0}^n\frac{k-q}{n-p}\cdot\frac{{k\choose q}{n-k\choose p-q}}{{n\choose p}}\cdot\frac{1}{n+1}}{\sum_{k=0}^n\frac{{k\choose q}{n-k\choose p-q}}{{n\choose p}}\cdot\frac{1}{n+1}} \\
&=\frac{\sum_{k=0}^n(k-q)\cdot{{k\choose q}{n-k\choose p-q}}}{(n-p)\sum_{k=0}^n{{k\choose q}{n-k\choose p-q}}} \\
&=\frac{(q+1)\sum_{k=0}^n{k\choose q+1}{n-k\choose p-q}}{(n-p)\sum_{k=0}^n{{k\choose q}{n-k\choose p-q}}} \\
&=\frac{q+1}{n-p}\cdot\frac{\sum_{k=0}^n{k\choose q+1}{n-k\choose p-q}}{\sum_{k=0}^n{{k\choose q}{n-k\choose p-q}}} \\
&=\frac{q+1}{n-p}\cdot\frac{{n+1\choose p+2}}{{n+1\choose p+1}} \\
&=\frac{q+1}{n-p}\cdot\frac{\frac{(n+1)!}{(p+2)!(n-p-1)!}}{\frac{(n+1)!}{(p+1)!(n-p)!}} \\
&=\frac{q+1}{n-p}\cdot\frac{n-p}{p+2} \\
&=\frac{q+1}{p+2}
\end{aligned}
\]
于是我们获得了一个 \(\mathcal O(1)\) 的式子 😃 .
参考代码 ¶
/** @author Arextre */
#include <bits/stdc++.h>
using namespace std;
#define USING_FREAD
// #define NDEBUG
// #define NCHECK
#include <cassert>
/** その可憐な少女は魔女であり、旅人でした。 ―― そう、私です! */
namespace Elaina {
#define rep(i, l, r) for(int i = (l), i##_end_ = (r); i <= i##_end_; ++i)
#define drep(i, l, r) for(int i = (l), i##_end_ = (r); i >= i##_end_; --i)
#define fi first
#define se second
#define mp(a, b) make_pair(a, b)
#define Endl putchar('\n')
#define whole(v) ((v).begin()), ((v).end())
#define bitcnt(s) (__builtin_popcount(s))
#define y0 FUCK_UP
#define y1 MOTHER_FUCKER
#ifdef NCHECK
# define iputs(Content) ((void)0)
# define iprintf(Content, argvs...) ((void)0)
#else
# define iputs(Content) fprintf(stderr, Content)
# define iprintf(Content, argvs...) fprintf(stderr, Content, argvs)
#endif
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
template<class T> inline T fab(T x) { return x < 0 ? -x : x; }
template<class T> inline void getmin(T& x, const T rhs) { x = min(x, rhs); }
template<class T> inline void getmax(T& x, const T rhs) { x = max(x, rhs); }
#ifdef USING_FREAD
inline char qkgetc() {
# define BUFFERSIZE 1 << 20
static char BUF[BUFFERSIZE], *p1 = BUF, *p2 = BUF;
return p1 == p2 && (p2 = (p1 = BUF) + fread(BUF, 1, BUFFERSIZE, stdin), p1 == p2) ? EOF : *p1++;
# undef BUFFERSIZE
}
# define CHARRECEI qkgetc()
#else
# define CHARRECEI getchar()
#endif
template<class T> inline T readret(T x) {
x = 0; int f = 0; char c;
while (!isdigit(c = CHARRECEI)) if(c == '-') f = 1;
for (x = (c ^ 48); isdigit(c = CHARRECEI); x = (x << 1) + (x << 3) + (c ^ 48));
return f ? -x : x;
}
template<class T> inline void readin(T& x) {
x = 0; int f = 0; char c;
while (!isdigit(c = CHARRECEI)) if (c == '-') f = 1;
for (x = (c ^ 48); isdigit(c = CHARRECEI); x = (x << 1) + (x << 3) + (c ^ 48));
if (f) x = -x;
}
template<class T, class... Args> inline void readin(T& x, Args&... args) {
readin(x), readin(args...);
}
template<class T> inline void writln(T x, char c = '\n') {
if (x < 0) putchar('-'), x = -x;
static int __stk[55], __bit = 0;
do __stk[++__bit] = x % 10, x /= 10; while (x);
while (__bit) putchar(__stk[__bit--] ^ 48);
putchar(c);
}
} // namespace Elaina
using namespace Elaina;
int n, p, q;
signed main() {
cin.tie(NULL)->sync_with_stdio(false);
for (int t = 1; cin >> n >> p >> q; ++t)
printf("Case %d: %.4f\n", t, (q + 1.0) / (p + 2.0));
return 0;
}