标签:clu 科学 print using 设计 发展 合数 计数 orange
组合数学是数学的重要组成部分,是一门研究离散对象的科学,它主要研究满足一定条件的组态(也称组合模型)的存在、计数以及构造等方面的问题。组合数学的主要内容有组合计数、组合设计、组合矩阵、组合优化等。
随着计算机科学的日益发展,组合数学的重要性也日渐凸显,因为计算机科学的核心内容是使用算法处理离散数据。
今天我们来研究组合数学中的一个有趣的问题,也是一个简单的计数问题:
从一副含有n(n≤10000)张的扑克牌[显然每张扑克牌都不相同]中,分给m(m≤100)个人,第i个人得到ai (0≤ai≤100)张牌,求一共有几种分法,这个数可能非常大,请输出此数模10007后的结果。
输入格式:
第一行两个整数 为 n m
第二行 m个整数 ai
输出格式:
此数模10007后的结果
【样例输入1】 5 2 3 1 【样例输入2】 20 19 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
【样例输出1】 20 【样例输出2】 8707
【数据规模】对于50%的数据,M = 1。
我们单看每一个人,一个人从n张牌中拿m张牌,那么它有c[m][n]中情况,然后我们拿完这些牌后剩下n-m张牌,、、、以此类推、、
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define N 10010 #define mod 10007 using namespace std; int c[N][110],n,m,x,ans; int read() { int x=0,f=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar(); return x*f; } int main() { n=read(),m=read(); c[0][0]=1;ans=1; for(int i=1;i<=n;i++) for(int j=0;j<=min(100,i);j++) c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod; while(m--) { x=read(); ans=1ll*ans*c[n][x]%mod; n-=x; } printf("%d",ans); return 0; }
标签:clu 科学 print using 设计 发展 合数 计数 orange
原文地址:http://www.cnblogs.com/z360/p/7892197.html