NOIP模拟 排队(组合数学)
【题目描述】
在成都某中学有m个男生与n个女生排队,这个学校的女生比较古怪,从某个位置(包含这个位置)开始往前数,男生的数量超过了女生的数量,女生会感觉不安全,于是会大叫起来,为了构建和谐校园,安排队伍时应该避免这样的情况。请你计算出不会引发尖叫的排队方案的概率。(排队方案不同定义:当且仅当某个某个位置人不一样,如男生A、男生B ,与男生B、男生A ,2个排列是不同方案)
【输入格式】
第一行1个整数, 表示测试数据的组数。
每个数据 有两个数 N,M(N个女生,M个男生)
【输出格式】
对于每组数据,输出一个实数(保留到小数点后 6 位)
【样例输入】
3
1 0
0 1
1 1
【样例输出】
1.000000
0.000000
0.500000
【备注】
30%的数据: (测试组数<=10),(0<=N,M<=1000).
100%的数据: (测试组数=9008 ), ( 0<=N,M<=20000 ).
【题目分析】
成功推了一个错误的式子,爆零滚粗。。。
这个题可以考虑数形结合的思想,将问题看作在二维平面上行走。女生看成移动(1,1),男生看成移动(1,-1),那么最后落在(n+m,n-m)处。
所以在移动过程中,一旦纵坐标小于0,那么就一定对应一种非法方案,这时可将其看做从(0,-2)出发到(n+m,n-m)处,那么向上就多走了一步,向下少走了一步,最后合法方案数即为C(m+n,m)-C(m+n,m-1),最后答案就是1-m/(n+1)。(注意答案最后可能小于0,所以需取二者较大值)
【代码~】
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<queue>
using namespace std;
const int MAXN=20001;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
double ans=0;
double n,m;
scanf("%lf%lf",&n,&m);
printf("%.6lf\n",1.0-m/(n+1));
}
return 0;
}