【Codeforces Beta Round #26 D】Tickets

题目链接

Tickets

Introduce

As a big fan of Formula One, Charlie is really happy with the fact that he has to organize ticket sells for the next Grand Prix race in his own city. Unfortunately, the finacial crisis is striking everywhere and all the banknotes left in his country are valued either \(10\) euros or \(20\) euros. The price of all tickets for the race is \(10\) euros, so whenever someone comes to the ticket store only with \(20\) euro banknote Charlie must have a \(10\) euro banknote to give them change. Charlie realize that with the huge deficit of banknotes this could be a problem. Charlie has some priceless information but couldn't make use of it, so he needs your help. Exactly \(n+m\) people will come to buy a ticket. \(n\) of them will have only a single \(10\) euro banknote, and \(m\) of them will have only a single \(20\) euro banknote. Currently Charlie has k \(10\) euro banknotes, which he can use for change if needed. All \(n+m\) people will come to the ticket store in random order, all orders are equiprobable. Return the probability that the ticket selling process will run smoothly, i.e. Charlie will have change for every person with \(20\) euro banknote.

Input

The input consist of a single line with three space separated integers, \(n\),\(m\) and \(k\) \((0 \le n,m \le 10^5,0 \le k \le 10)\).

Output

Output on a single line the desired probability with at least \(4\) digits after the decimal point.

Examples

Input

5 3 1

Output

0.857143

Input

0 5 5

Output

1

Input

0 1 0

Output

0

题解

题意:你要卖价值\(10\)元的票,你现在有\(k\)\(10\)元,有\(n+m\)个人要来买票,\(n\)个人用\(10\)元来买票,\(m\)个人用\(20\)元来买票,求这\(n+m\)个人按照随即顺序来买票,能把票卖给所有人的概率是多少。
那么我们很容易就想到这样一个性质:

  • 客户用\(10\)元来买,就是增加一张你手上的\(10\)元。
  • 用户用\(20\)元来买,就是减少一张你手上的\(10\)元。

那么题目就变成了当前的值为\(k\)\(n\)\(+1\)操作,\(m\)\(-1\)操作,这个值大于等于\(0\)的概率。
那么我们很容易就想到了卡特兰数。
但是这个题目的卡特兰数和普通的卡特兰数有点不同。
我们用一幅\(n*m\)的矩形,\(x\)轴表示用\(10\)元的人,\(y\)轴表示用\(20\)元的人。
一条斜线表示如果\((0,0)\)\((n,m)\)的路径不超过这条线,那么这条路径是合法的。
如图:

那么问题就转化为合法路径除以总路径数。
总路径数就是\(C(n+m,n)\)
那么接下来的问题就是如何求合法路径数了。
我们考虑如果求出不合法路径数,那么合法路径数也就知道了。
如果我们把这条斜线往上移一个单位就会发现只要是经过这条斜线的路径,都是不合法的。
那么我们看一下下图:

绿色的点是\((0,0)\),关于红色斜线的对称点,因为从绿色的点到\((n,m)\)必定经过红色的线,
那么我们就可以把绿色的点到\((n,m)\)的路径看成从\((0,0)\)\((n,m)\)经过红色的线的路径,也就是不合法路径。
那么最终答案就变成了:\(1-C(n+m,m-k-1)/C(n+m,n)\)
那么我们就可以算出答案了。
但是我们会发现这样一个问题,答案要求输出的是四位小数,但是如果你先分别算出两个组合数,那么你就会发现这个数太大了,如果用\(double\)存会爆空间。
所以我们把这个组合数拆开来,化简成\(n!*m!/((m-k-1)!*(n+k+1)!)=\frac{(m!/((m-k-1)!)}{((n+k+1)!/n!))}\),我们发现分子和分母的因子数(阶乘约分后的因子)是一样的,那么我们一个\(for\)循环就好了,可以把答案控制在一定大小之内。
具体实现可以看代码。
上代码:

#include<bits/stdc++.h>
using namespace std;
int n,m,k;
double ans;
int main(){
    scanf("%d%d%d",&n,&m,&k);
    if(n+k<m){printf("0");return 0;}
    if(k>=m){printf("1");return 0;}
    double ans=1;
    for(int j=1;j<=k+1;j++)
        ans=ans*(m-k-1+j)/(n+j);
    printf("%.4lf",1-ans);
    return 0;
}
posted @ 2019-11-10 22:28  oblivionl  阅读(93)  评论(0编辑  收藏  举报