Fork me on GitHub

SCAU 8635 气球

8635 气球

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

题型: 编程题   语言: 无限制

Description

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

Input

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

Output

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

Sample Input

3 1
3

Sample Output

1

Hint

Sample Input2:
4 2
2 2
Sample Output2:
3

Source

Ick2

Provider

admin

 

#include<stdio.h>
#include<string.h>
int option1(int m, int times)
{
    int i, res = m;
    while(--times)
    res *= (--m);
    return res;
}
 
//函数option1和option2主要计算Cm取n,在option1中有m*(m-1)*.....*(m-times+1)
//option2函数计算n!

int option2(int n)
{
    if(n == 1 || n == 2) return n;
    else return n*option2(n-1);
}

int main()
{
    int n, m,  depart[11], i, j, temp, count, mis, res;
    memset(depart, 0, sizeof(depart));
    scanf("%d%d", &n, &m);
    for(i=0; i<m; ++i)
    {
        scanf("%d", &temp);
        depart[temp]++;
    }
    res = count = mis = 1;
    for(i=1; i<=10; ++i)
    {
        count = mis = 1;
        if(depart[i] !=0)
        {
            temp = depart[i];
            while(temp--)
            {
                count  *= (option1(n, i)/option2(i));
                n -= i;
            }
            res =res * count/(option2(depart[i])) ;
        }
    }
    printf("%d\n", res);

    return 0;
}


解题报告:

看到这题目,虽然有种熟悉的感觉,但更多的还是害怕,因为对于排列组合的知识差不多都忘光了。

本题主要处理分堆后,堆中的气球数量相同的情况,这时变成了组合的问题而不需要排序,处理的办法是先将此看为排序,然后只取排序中的一种情况即可,而只取一种的

操作方法是除以相同数目堆的堆数的阶乘。

 

posted @ 2012-11-24 20:46  Gifur  阅读(411)  评论(0编辑  收藏  举报
TOP