http://acm.hdu.edu.cn/showproblem.php?pid=4061
题意:有M堆牌,每堆分别有a[i]张,编号为i的牌共有a[i]张, 现在随机将这些牌分成M组,每组a[i]张,游戏从1号堆开始,每次取出一张牌,记下该牌的编号为j,丢弃该牌,然后从j号堆开始继续游戏, 直至到一个不能 取数的堆为止,游戏结束。问游戏结束的时候,所有堆都为空的概率是多少。
分析:直接去考虑随机分牌,然后随机取的具体过程显然会很复杂,这里可以换一个思路考虑:在丢弃牌的顺序中,第i张牌的后面的牌j一定是在i堆中的(这个结论是显然的),要达到目标(将所有的牌丢弃),就需要所有的牌出现在丢弃的序列中,a[i]个i在序列中,只要i不在序列的最后,就一定会有一定后缀,即一定会有a[i]个数在堆i中。因为最开始时从堆1开始的,也就是说,在序列的最后就一定是要1,因为如果最后一个数不是1的话(假设为i),则在整个序列中,i只有i-1个后缀,也就说明,i堆只有i-1张牌,这是不行的。 因此整个序列只要求最后一个数是1就可以了,其他的都可以随便排。 因此题目就是求n个数的全排列,然后要求最后一个数是1 的概率,a[1] / sum ;
代码:
#include<stdio.h>
int a[101] ;
int main()
{
int T,m,ncase=1;
scanf("%d",&T);
while(T--)
{
scanf("%d",&m);
int sum = 0 ;
for(int i=1;i<=m;i++)
{
scanf("%d",&a[i]);
sum += a[i] ;
}
printf("Case %d: %.6f\n",ncase++,a[1]*1.0/sum);
}
return 0 ;
}
反思:其实这题一开始貌似YY出来应该是这个结果,但是一直在寻找证明,一直没有找到,就开始掉入了无止尽的分析中间过程
中。。。 囧。。 开始好好学习学习数学了。。。