c/c++语言开发共享P1358 扑克牌

题目描述 组合数学是数学的重要组成部分,是一门研究离散对象的科学,它主要研究满足一定条件的组态(也称组合模型)的存在、计数以及构造等方面的问题。组合数学的主要内容有组合计数、组合设计、组合矩阵、组合优化等。 随着计算机科学的日益发展,组合数学的重要性也日渐凸显,因为计算机科学的核心内容是使用算法处理 …


题目描述

组合数学是数学的重要组成部分,是一门研究离散对象的科学,它主要研究满足一定条件的组态(也称组合模型)的存在、计数以及构造等方面的问题。组合数学的主要内容有组合计数、组合设计、组合矩阵、组合优化等。

随着计算机科学的日益发展,组合数学的重要性也日渐凸显,因为计算机科学的核心内容是使用算法处理离散数据。

今天我们来研究组合数学中的一个有趣的问题,也是一个简单的计数问题:

从一副含有 nn 张的扑克牌(每张扑克牌都不相同)中,分给 mm 个人,第 ii 个人得到 a_iai 张牌,求一共有几种分法,这个数可能非常大,请输出此数模 1000710007 后的结果。

输入格式

第一行两个整数为 n,mn,m。

第二行 mm 个整数 a_iai

输出格式

此数模 1000710007 后的结果。

输入输出样例

输入 #1

5 2 3 1 

输出 #1

20 

输入 #2

20 19 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 

输出 #2

8707 

说明/提示

对于 50%50% 的数据:m=1m=1。

对于 100%100% 的数据:1 leq n leq 10^41n104,1 leq m leq 1001m100,0 leq a_i leq 1000ai100。

解析:题目很容易发现用到是组合数和乘法原理。

给第1个人分配的方法数为:c(n,a[1]);

给第2个人分配的方法数为:c(n-a[1],a[2]);

给第n个人分配的方法数为:c(n-a[1]-a[2]-…a[n-1],a[n]);

利用乘法原理,总的方法数为:c(n,a[1])*c(n-a[1],a[2])*…*c(n-a[1]-a[2]-…a[n-1],a[n])

利用杨辉三角,提前算出所有的组合数。注意m<=100,也就是最多用到杨辉三角第100列的数。

P1358 扑克牌

 

 代码如下:

#include<iostream> #include<cstdio> using namespace std; const int maxm=110; int n,m,sum=1; int a[maxm],f[10010][maxm]; int main(){ 	scanf("%d%d",&n,&m); 	for(int i=1;i<=m;i++) scanf("%d",&a[i]); 	f[0][0]=1; 	f[1][0]=1;f[1][1]=1; 	for(int i=2;i<=n;i++){ 		f[i][0]=1; 		for(int j=1;j<=min(i,100);j++){//m最大为100,也就是最多用到第100列的值  			f[i][j]=(f[i-1][j-1]+f[i-1][j])%10007; 		//	cout<<f[i][j]<<" "; 		} 	//	cout<<endl; 			 	}	 	for(int i=1;i<=m;i++){ 	//	cout<<sum<<" "; 		sum=(sum*f[n][a[i]])%10007; 	//	cout<<f[n][a[i]]<<endl; 		n-=a[i]; 	} 	printf("%dn",sum);				 	return 0; } 

  

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/599617.html

(0)
上一篇 2021年5月9日
下一篇 2021年5月9日

精彩推荐