2013长春网赛1004 hdu 4762 Cut the Cake

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4762

题意:有个蛋糕,切成m块,将n个草莓放在上面,问所有的草莓放在同一块蛋糕上面的概率是多少。2 < M, N <= 20

分析:概率题,公式题。可惜我数学太差,想了好久都想不出来,看了题解还是不太明白怎么算的。

最后的概率公式为:n / (m^(n-1)),然后用高精度就可以了,最后的结果要约分,可以在计算的过程中求gcd(n,m),然后分子分母同除以该数就可以了。

这里有两个方法可以推出来。

方法1:以落在最左边的一颗来考虑,其余落在其右边的概率为1/m^(n-1),考虑每一个都可能在最左,实际上就是乘以c(1,n)

这样就可以推出公式为:n / (m^(n-1))

感觉这个方法不太严谨。。。。

方法2:(用积分求的)

枚举两个点位于两边,就是A(n,2)=n*(n-1),然后两个点形成的角度范围在0~1/m之间,

剩下的n-2个点放的概率就是x^(n-2),所以积分0~1/m,x^(n-2)对x进行积分。

积分结果乘上n*(n-1)就行了

用的是c++大数模板

AC代码:

 1 #include<stdio.h>
 2 #include<string.h>
 3 struct BigNum{
 4     int num[100];
 5     int len;
 6 };
 7 int gcd(int a,int b)
 8 {
 9     if(b==0)
10         return a;
11     return gcd(b,a%b);
12 }
13 BigNum mul(BigNum &a,int b)
14 {
15     BigNum c;
16     int i,len;
17     len=a.len;
18     memset(c.num,0,sizeof(c.num));
19     if(b==0)
20     {
21         c.len=1;
22         return c;
23     }
24     for(i=0;i<len;i++)
25     {
26         c.num[i]+=(a.num[i]*b);
27         if(c.num[i]>=10)
28         {
29             c.num[i+1]=c.num[i]/10;
30             c.num[i]%=10;
31         }
32     }
33     while(c.num[len]>0)
34     {
35         c.num[len+1]=c.num[len]/10;
36         c.num[len++]%=10;
37     }
38     c.len=len;
39     return c;
40 }
41 int main()
42 {
43     int t,m,n,i,a,b,c;
44     BigNum s;
45     scanf("%d",&t);
46     while(t--)
47     {
48         scanf("%d%d",&m,&n);
49         s.num[0]=1;
50         s.len=1;
51         a=n;
52         for(i=1;i<n;i++)
53         {
54             b=m;
55             c=gcd(a,m);
56             a/=c;
57             b/=c;
58             s=mul(s,b);
59         }
60         printf("%d/",a);
61         for(i=s.len-1;i>=0;i--)
62             printf("%d",s.num[i]);
63         printf("
");
64     }
65     return 0;
66 }
View Code
原文地址:https://www.cnblogs.com/frog112111/p/3349065.html