Description
You are one of
2k
competitors invited to enter a single elimination tournament. You are ranked
r
th in the published rankings. Furthermore, you know that in any match between two players, the one ranked higher will always win.
The only source of uncertainty is the bracket. If every possible tournament bracket is equally likely, determine your expected number of wins in the tournament. Your expected number of wins is the average number of your wins over all possible tournament bracket orderings.
Translation
一次淘汰赛有
Input
The input consists of a single line containing the two space-separated integers k(1≤k≤20) and r(1≤r≤2k) .
Output
Print, on a single line, your expected number of wins in the tournament, rounded and displayed to exactly five decimal places. The sixth digit after the decimal point of the exact answer will never be 4 or 5 (eliminating complex rounding considerations).
Be careful about very small or very large numbers during intermediate steps.
Sample 1
Sample Input
3 3
Sample Output
1.00000
Sample 2
Sample Input
20 130
Sample Output
11.65203
Solution
队友在virtual contest的时候想的DP,然后没想出来。。输出结果比样例大。
这道题呢。。
假设你能胜
i
次,也就是说至少要打
那么显然至少能战胜
也就是说,所有的情况是从 2k−1 个人里面随机地选出 2i−1 将会和你比赛。但是你要 i 场都胜出,因此是在
因此假设只战胜 i 次(而不是至少)的概率为
显然 Q(i)=∑nj=iP(i) ,那么结果就为
但是计算组合数嘛。。因为阶乘结果很大然后我们又只需要计算比值,我们可以取对数解决。
Code
#include <cstdio>
#include <cmath>
const int N = 1 << 21;
double logFac[N];
double logC(int n, int m) {
return logFac[n] - logFac[m] - logFac[n - m];
}
int main() {
int k, r, i, n, m;
double ans;
for (i = 1; i <= (1 << 20); ++ i)
logFac[i] = logFac[i - 1] + log(i);
scanf("%d%d", &k, &r);
n = 1 << k;
ans = 0;
for (i = 1; i <= k; ++ i) {
m = (1 << i) - 1;
if (n - r < m) break;
ans += exp(logC(n - r, m) - logC(n - 1, m));
}
printf("%.5f\n", ans);
return 0;
}