8635 气球(组合数)

8635 气球

该题有题解

时间限制:500MS  内存限制:1000K
提交次数:204 通过次数:58

题型: 编程题   语言: G++;GCC

 

Description

    一天,OYY 从外面打完比赛回来,手上拿了很多个气球,颜色各不相同。他见到我,就说,你看,我拿了很多气球!
我膜拜死了!!然后他就问了我一个问题,如果把这里的气球分成若干份。有多少种分法呢?
    由于我数学非常菜,顿时头晕了,因此希望大家能帮我解答这个问题(@_@))




输入格式

输入数据有2行
第1 行有两个数n,m,分别代表oyy 手上的气球个数和分的份数(n<=10,m<=5)
第2 行有m 个数,分别代表每一份的个数,保证总个数等于n



输出格式

输出数据有1行,输出一个数代表不同分法的总数。



 

输入样例

3 1
3



 

输出样例

1



 

提示

Sample Input2:
4 2
2 2
Sample Output2:
3

 

题解

由于气球是不同的,假设有n个气球,第一份气球要拿a个,那么就有C(n,a)种情况,假设第二分有b个,那就是C(n,a)*C(n-a,b)种。。。最后一堆不用算,直接是1,注意气球个数可能重复,假设都为k,那答案就要除以一个A(k,k)

 

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int C(int a,int b)
{
    long long s1=1,s2=1;
    for (int i=1;i<=b;i++)
    {
        s1*=a;
        a--;
        s2*=i;
    }
    return s1/s2;
}
int A(int a,int b)
{
    int ans=1;
    for (int i=1;i<=b;i++)
    {
        ans*=a;
        a--;
    }
    return ans;
}
int d[20];
int main()
{
    int a,b,c[20];
    int ans=1;
    scanf("%d%d",&a,&b);
    for (int i=0;i<b;i++)
    {
        scanf("%d",&c[i]);
        d[c[i]]++;
    }
    int i=0;
    for (;i<b-1;i++)
    {

        ans*=C(a,c[i]);
        a-=c[i];
    }
    for (int i=0;i<20;i++)
    if (d[i]>1)
    {
        ans/=A(d[i],d[i]);
    }
    printf("%d",ans);
    return 0;
}

 

posted @ 2016-05-26 20:24  酱油党gsh  阅读(315)  评论(2编辑  收藏  举报