1. 程式人生 > >NOIP模擬 排隊(組合數學)

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