解题思路: 这个题目直接求合理的排序比较烦琐,采用模拟的方法也显然不行。可以先考虑可以实现的概率,再用实际的总次数去乘。 先把所有的n个拿50的人排好,接下来再把拿100的人插入队列。求可行的概率。 n个拿50的人有n+1个空位,除了第一个以外,其他的位置都可以,所以概率是n/n+1,在以上的基础下,第2个的的概率是n-1/n(由于是求概率,所以可以把所有的拿50或100的人看成是一样的,在这个前提下可以认为第一个拿50的人和第一个拿100的人一起消失了。为什么可以这么认为?由于在求概率,不去除的化会重复计算,具体读者自己思考)。 同理直到最后一个拿100的插入队列,他成功的概率是n-m+1/n-m+2。 以上所有都发生,才使最后的队伍满足要求。所以最后成功的概率是n-m+1/n+1。再乘上全部的排列就是答案(m+n)!*(n-m+1)/(n+1) 最好高精度处理

这题也可以用组合数学的路程方法求解 公式为 C(m+n,m)-C(m+n,m-1)=(m+n)!(n-m+1)/(m!(n+1)!)

#include <iostream>
#include <string.h>
using namespace std;
#define MAX_LENGTH 400                         //最长的数字的长度
typedef struct long_int                         //定义了长数的结构
{
    char num[MAX_LENGTH];                       //具体的每一位上的数字
    int l;                                   //数字的长度
}long_int;
void init_long_int(long_int &a)                 //初始化全部为0
{
    memset(&a,0,sizeof(a));
}
long_int int_to_long_int(int x)                 //返回x对应的长数,错误就打印错误
{
      long_int a;
      init_long_int(a);
      while (x!=0)
      {
          a.num[a.l++]=x%10;
          x/=10;
      }
      return a;
}
long_int multiply_int(long_int &a,int b)           //乘法函数,返回a*b
{
      int jwei,temp,i,j;                     //进位,临时变量
      long_int c;                           //最终结果存放
      init_long_int (c);
      jwei=0;temp=0;i=0;j=0;
      //以上变量初始化
      if(b==0) return c;
      for(i=0;i<a.l;i++)
      {
            temp=jwei+b*a.num[i];
            c.num[i]=temp%10;
            jwei=temp/10;
      }
      c.l=i;
      while (jwei>0)
      {
          c.num[c.l++]=jwei%10;
          jwei/=10;
      }
      return c;
}
void long_int_printf(long_int &x)                 //长数打印函数
{
      for (int i=x.l-1;i>=0;i--)
          printf("%c",x.num[i]+48);
      return ;
}
int main()
{
    void init_long_int(long_int &a);             //初始化函数a=0
    long_int int_to_long_int(int x);           //返回x对应的长数,错误就打印错误
    long_int multiply_int(long_int &a,int b);       //乘法函数,返回a*b(b是一般长度的)
    void long_int_printf(long_int &x);           //长数打印函数
    int a,b,i,t=0;
    long_int x;
    while (cin>>a>>b&&(a||b))
    {
        t++;
        cout<<"Test #"<<t<<':'<<endl;
        if (b>a)
        {
            cout<<0<<endl;//无解输出0
            continue;
        }
        x=int_to_long_int(1);
        for (i=2;i<=(a+b);i++)                     //介乘计算
            if (i!=a+1) x=multiply_int(x,i);             //避免除法,跳过分母
        if (b!=0) x=multiply_int(x,(a-b+1));             //这种情况,分母不该被跳过
        long_int_printf(x);
        cout<<endl;
    }
    return 0;
}

results matching ""

    No results matching ""