思路1:
详解
当m<n时,明显不可能,输出0即可。
当m>=n时,对于一个不满足要求的m个50,n个100的序列,其对应着一个m+1个100,n-1个50的必然不成立的序列。
那么全部的可能序列的个数为:C [n+m] [m],而不符合要求的序列的个数为C[n+m][m+1],
所有答案为C[n+m][m]-C[n+m][ m+1]。
又因为 每个人都不同,所以要乘以m!*n!。
化简为(m+n)! *(m-n+1)/(m+1)。
(当m=n时,为卡特兰数)
思路2:
详解
用递推写,

#include <bits/stdc++.h>
using namespace std;
struct node
{
    int num[100];//压位10000
    node operator *(const int b)const
    {
        node res;
        memset(res.num,0,sizeof(res.num));
        for(int i=1;i<=num[0];i++)
            res.num[i]=num[i]*b;
        res.num[0]=num[0]+3;
        for(int i=1;i<=res.num[0];i++)
        {
            res.num[i+1]+=res.num[i]/10000;
            res.num[i]%=10000;
        }
        while(res.num[res.num[0]]==0)
            res.num[0]--;
        return res;
    }
    node operator /(const int b)const
    {
        node res;
        memset(res.num,0,sizeof(res.num));
        int t=0;
        for(int i=num[0];i>=1;i--)
        {
            t=t*10000+num[i];
            res.num[i]=t/b;
            t%=b;
        }
        res.num[0]=num[0];
        while(res.num[res.num[0]]==0)
            res.num[0]--;
        return res;
    }
    void print()
    {
        printf("%d",num[num[0]]);
        for(int i=num[0]-1;i>=1;i--)
            printf("%.4d",num[i]);
        printf("\n");
    }
};
node A[205];
void init()
{
    A[0].num[0]=1;
    A[0].num[1]=1;
    A[1].num[0]=1;
    A[1].num[1]=1;
    for(int i=2;i<=200;i++)
        A[i]=A[i-1]*i;
}
int main()
{
    int n,m,cas=0;
    init();
    while(scanf("%d%d",&m,&n),n!=0||m!=0)
    {
        printf("Test #%d:\n",++cas);
        if(m<n)
            printf("0\n");
        else
        {
            node ans=A[m+n]*(m-n+1)/(m+1);
            ans.print();
        }
    }
    return 0;
}
//也可以用递推式:ans[m][n]=ans[m-1][n]+ans[m][n-1];其中m>=n
//

一道类似的题:hdu1267
思路

#include <bits/stdc++.h>
using namespace std;
long long ans[25][25];
void init()
{
    for(int i=0;i<=20;i++)
        for(int j=0;j<=i;j++)
            ans[i][j]=1;
    for(int i=2;i<=20;i++)
    {
        for(int j=1;j<=i;j++)
            ans[i][j]=ans[i-1][j]+ans[i][j-1];
    }
}
int main()
{
    int n,m;
    init();
    while(scanf("%d%d",&m,&n)!=EOF)
    {
        if(m<n)
            printf("0\n");
        else
            printf("%lld\n",ans[m][n]);
    }
    return 0;
}

对应m个H,n个D的序列,其相对于在m个H,n-1个D的序列后面加上一个D,在m-1个H,n个D序列后面加上一个H。即ans[m][n]=ans[m-1][n]+ans[m][n-1]。
用笔手推一下,画一个表格。