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; }