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; }
解题报告:
看到这题目,虽然有种熟悉的感觉,但更多的还是害怕,因为对于排列组合的知识差不多都忘光了。
本题主要处理分堆后,堆中的气球数量相同的情况,这时变成了组合的问题而不需要排序,处理的办法是先将此看为排序,然后只取排序中的一种情况即可,而只取一种的
操作方法是除以相同数目堆的堆数的阶乘。