• best coder #35-01<组合数学 || 概率数学>


    问题描述
    一个盒子里有n个黑球和m个白球。现在DZY每次随机从盒子里取走一个球,取了n+m次后,刚好取完。DZY用这种奇怪的方法生成了一个随机的01串S[1(n+m)]。如果DZY第i次取出的球是黑色的,那么S[i]=1,如果是白色的,那么S[i]=0。
    DZY现在想知道,'01'在S串中出现的期望次数。
    输入描述
    输入有多组测试数据。 (TestCase150)
    每行两个整数, n, m(1n,m12)
    输出描述
    对于每个测试数据,输出一行答案,格式为p/q(p,q互质)。
    输入样例
    1 1
    2 3
    输出样例
    1/2
    6/5
    Hint
    Case 1: S='01' or S='10', 所以期望次数 = 1/2
    Case 2: S='00011' or S='00101' or S='00110' or S='01001' or S='01010' 
    or S='01100' or S='10001' or S='10010' or S='10100' or S='11000',
    所以期望次数 = (1+2+1+2+2+1+1+1+1+0)/10 = 12/10 = 6/5
    *************************************************************************************************
    本题的官方解释是数学:
    第i位上出现0,第i+1位出现1,这种概率是:(m/(n+m))*(n/(n+m-1)),0的位置可以出现在第一个一直到倒数第二个;所以累加(n+m-1),相承,公式是n*m/(n+m);

    我的做法不是这样,组合数学:
    刚开始看作所有的1发个在最左边,0放在最右边,一共最多有n或m个01串,(个数是其中较小的那个),枚举串的个数从1到最大,当有1
    个01串的时候,从n个1中取一个空当,用来插入0,从m个0中可以选1个0放到空档里,也可以选两个一直到选m个,所以对于每一个1都有m种插法,c(n,1)*c(m,1)*1;
    当有两个01串的时候,取1,c(n,2),取0,第一个1有1到m-1种插法,第二个1有剩余的插法,组合数公式,c(m,2);c(n,2)*c(m,2)*2;
    累加下去
    总共的排列数就是c(n+m,n);
    相比一下,约分,就得到答案了;


    代码如下:
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<string>
     5 #include<cstring>
     6 #define ll long long
     7 using namespace std;
     8 int N,M;
     9 long long k,t;
    10 long long zuhe(ll n,ll x)
    11 {
    12     ll di=1,gao=1,ans=1;
    13     for(ll i=1;i<=x;i++)
    14     { 
    15         di*=n;
    16         n--;
    17         gao*=i;
    18     }
    19     return di/gao;
    20 }
    21 void yuefen(ll a,ll b)
    22 {
    23     for(ll i=b;i>=1;i--)
    24     {
    25         if(a%i==0&&b%i==0)
    26         {
    27             k=a/i;
    28             t=b/i;
    29             return ;
    30         }
    31     }
    32 }
    33 int main()
    34 {
    35 //    freopen("in","r",stdin);
    36 //    freopen("out.out","w",stdout);
    37     while(scanf("%d%d",&N,&M)!=EOF)
    38     {
    39         k=0;
    40         t=0;
    41         for(ll i=1;i<=N;i++)
    42         {
    43             ll temp=0;
    44             if(i>M)
    45                 break;
    46             t+=i*zuhe(N,i)*zuhe(M,i);
    47         }
    48         k=zuhe(N+M,M);
    49         yuefen(k,t);
    50         printf("%I64d/%I64d
    ",t,k);
    51     }
    52     return 0;
    53 }
    View Code
  • 相关阅读:
    电梯设计需求调研报告
    返回一个整数数组中最大子数组的和。
    返回一个整数数组中最大子数组的和
    四则运算2程序及运行结果
    四则运算2
    上半学期读软件工程方面著作的读书计划
    写输出30道小学生四则运算程序的解题思路及未在规定时间内完成程序的原因
    《人月神话》读后感
    阅读《软件工程—理论方法与实践》第十一章心得体会
    java常见排序方法
  • 原文地址:https://www.cnblogs.com/by-1075324834/p/4413399.html
Copyright © 2020-2023  润新知