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;
}

 

posted @ 2018-10-04 14:48  Ishtar~  阅读(200)  评论(0编辑  收藏  举报