【组合数学】“派送食物问题”
2015-04-01 08:47
302 查看
题目
问题描述 Lucy 和Lily 是一对双胞胎,在Lucy 和Lily 十岁生日的时候,她们举办了一个晚会。晚会上,Tom 负责派送食物。Tom 手上有两种食物,汉堡和三明治。晚会上的20 个孩子围成一圈,Tom 拿了10 个汉堡和10 个三明治,进行分发。为了保证公平,Tom 采用丢硬币的方法,正面给汉堡,背面给三明治。Lucy 和Lily 被按排到最后再拿食物,但当Tom 发到第19 个人Lucy 的时候,这时候只有两个汉堡了,于是他不再丢硬币了,让最后两个人都拿汉堡。Lucy 和Lily 因此都拿了汉堡。 对此,Tom 很好奇,他非常想知道当n(n 为偶数)个人围成一圈的时候,分发n/2 个 汉堡,n/2 个三明治,Lucy 和Lily 最后两个拿食物,她们拿到同样食物的概率。 数据输入 第一行整数k,测试数据的组数,接下来k 行,每行一个偶整数n。其中,n 的取值范围是[2,4,6…100000]。 数据输出 对于每组测试数据,输出Lucy 和Lily 拿到同样食物的概率。输出四舍五入保留3 位有 效数字。 样例输入输出 样例输入 3 6 10 256 样例输出 0.625 0.727 0.950 数据说明 30%的测试数据n 的取值范围小于50。 70%的测试数据n 的取值范围小于等于1000。 100%的测试数据n 的取值范围小于等于100000。
这完全就是一道数学题啊。。。由于我十分愚钝,丝毫不会。。。
我们先把题解发出来
所以最后两个数不同的概率是C(n-2,n/2-1)*(1/2)^(n-2)。 因此,最后两个数相同的概率就是 1- C(n-2,(n/2-1)*(1/2)^(n-2)。 由于n实在太大了,在计算的时候要注意乘法和除法的结合,既要避免浮点数溢出,又要避免精度降到0之下。
上来那个“所以”弄得我莫名其妙,不知道这式子怎么蹦出来的(当然神犇们一看题一眼就会了)。下面给出我愚蠢的过程。
我先敲了如下的模拟(数学课本上说,不好算的概率,可以用计算机模拟)
var a,b,tot,i,c,n:longint; begin randomize; tot:=10000000; c:=0; n:=10; for tot:=1 to tot do begin a:=n>>1;b:=n>>1; for i:=1 to n-2 do if random(2)=1 then dec(a) else dec(b); if (a<=0)or(b<=0) then inc(c); //if (a=0)or(b=0) then inc(c); end; writeln(c/tot:0:3); end.
这个模拟充斥着我迂腐的思想。。。我在注释的那一行纠结了很长时间,后来觉得就是小于等于零,而不是等于零,因为小于零对应着某一种“提前取完”。(其实把样例输进去看下就知道了“)。
通过这个模拟我们发现符合要求的情况就是n-2个数,每个可以取0或1,取得大于等于n/2个0或1。
这样就和题解上的一样了,就剩下”由于n实在太大了,在计算的时候要注意乘法和除法的结合,既要避免浮点数溢出,又要避免精度降到0之下”的处理,我又用了愚蠢的方法,把组合数定义里的所有分子分母存起来,先乘法,太大之后做除法。
var t,n:longint; x,y:array[0..300000]of longint; function calc(n:longint):extended; var i,j,a,b:longint;ans:extended; begin b:=n-2; for i:=1 to b do y[i]:=2; a:=n>>1-1; for i:=1 to a do begin x[i]:=n-1-i; inc(b); y[b]:=i; end; ans:=1; i:=1; j:=1; //for i:=1 to b do write(y[i],' '); while i<=a do begin ans:=ans*x[i]; while (ans>1e15)and(j<=b) do begin ans:=ans/y[j];inc(j);end; inc(i); end; while j<=b do begin ans:=ans/y[j]; inc(j); end; exit(1-ans); end; begin assign(input,'food.in');reset(input); assign(output,'food.out');rewrite(output); readln(t); for t:=1 to t do begin read(n); writeln(calc(n):0:3); end; close(input);close(output); end.
相关文章推荐
- 传球问题(组合数学问题)
- 如何利用数学思想解1/2/5组合问题
- 【组合数学】36军官问题
- BZOJ 3028 食物 组合数学
- 关于数学组合问题在m个球中取n个球-递归实现
- C/C++面试之算法系列--如何利用数学思想解1/2/5组合问题
- Topcoder SRM661 ColorfulLineGraphs,数学组合问题+快速幂求解
- 04-06组合数学实践_交通问题
- 问题 A : 人生三大幻觉(组合数学)
- 组合数学——不过对角线的格路问题
- 如何利用数学思想解1/2/5组合问题
- 卡特兰数在多种问题下的应用 组合数学-Catalan数
- (组合数学3.3.2.2)UVA 10497 - Sweet Child Makes Trouble(特殊的排列问题——错排方案数)
- 【组合数学】36军官问题
- 组合数学第二发 错排问题 hdu 2049 + hdu 2068
- 错排问题(组合数学)
- java实现从M个元素中取N个元素的所有组合(数学中的组合问题)
- 相同数不能相邻的排列问题 组合数学-容斥原理
- 组合数学--错排问题
- 数学中排列组合各种问题