hdu 1133 Buy the Ticket

来源:互联网 发布:教孩子学编程python 编辑:程序博客网 时间:2024/06/08 04:13

题意:M+N个人排队买票,票的单价是50¥,每个人只能买一张。 M个人拿50的去买,N个人拿100的去买,然后悲剧的是售票处开始的时候没有钱,所以如果拿100块买票人前面的拿50块买票的人小于或者等于用100块买票的人,这种排队方式就不合法,也就是不能顺利全部都买到票(因为没零钱找了)!

题解:

该题的公式:(C(m+n, n)-C(m+n, m+1))*m!*n! 化简即(m+n)!*(m-n+1)/(m+1)

m个人拿50,n个人拿100 , 所以如果 n>m,那么排序方法数为 0 这一点很容易想清楚

现在我们假设 拿50的人用 ‘0’表示, 拿100的人用 1 表示。

如果有这么一个序列 0101101001001111..........
当第K个位置出现1的个数多余0的个数时就是一个不合法序列了
假设n=4 n=3的一个序列是:0110100 显然,它不合法, 现在我们把它稍微变化一下:
把第二个1(这个1前面的都是合法的)后面的所有位0变成1,1变成0
就得到 0111011 这个序列1的数量多于0的数量, 显然不合法, 但现在的关键不是看这个序列是不是合法的
关键是:它和我们的不合法序列 0110100 成一一对应的关系
也就是说任意一个不合法序列(m个0,n个1), 都可以由另外一个序列(n-1个0和m+1个1)得到
另外我们知道,一个序列要么是合法的,要么是不合法的
所以,合法序列数量 = 序列总数量 - 不合法序列的总量
序列总数可以这样计算m+n 个位置中, 选择 n 个位置出来填上 1, 所以是 C(m+n, n)
不合法序列的数量就是: m+n 个位置中, 选择 m+1 个位置出来填上 1 所以是 C(m+n, m+1)
然后每个人都是不一样的,所以需要全排列 m! * n!

题目还涉及到了大数乘小数,还有大数除小数


#include<stdio.h>#include<stdlib.h>#include<string.h>#include<iostream>using namespace std;int a[110];int n,m;void getfactor(int x)      //计算x的阶乘{    a[100] = 1;    for(int i = 2; i <= x; i++)    {        int ad = 0;        for(int j = 100; j >= 0; j--)        {            ad += a[j] * i;            a[j] = ad % 10000;            ad /= 10000;        }    }}void multiply(int x)        //计算大数乘以x{    int ad;    for(int i = 100,ad = 0; i >= 0; i--)    {        ad += a[i] * x;        a[i] = ad % 10000;        ad /= 10000;    }}void division(int x)        //计算大数除以x{    int ad = 0;    for(int i = 0; i <= 100; i++)    {        ad = ad * 10000 + a[i];        a[i] = ad / x;        ad %= x;    }}void output(){    int i;    for(i = 0; i <= 100; i++)    {        if(a[i])            break;    }    printf("%d",a[i++]);    for(; i <= 100; i++)        printf("%04d",a[i]);    printf("\n");}int main(){    int cases=1;    while(scanf("%d %d",&m,&n),m||n)    {        printf("Test #%d:\n",cases++);        if(m<n)            printf("0\n");        else        {            memset(a,0,sizeof(a));            getfactor(m+n);            multiply(m-n+1);            division(m+1);            output();        }    }    return 0;}



0 0