java P1358 扑克牌

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

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

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

从一副含有n(n≤10000)张的扑克牌[显然每张扑克牌都不相同]中,分给m(m≤100)个人,第i个人得到ai (0≤ai≤100)张牌,求一共有几种分法,这个数可能非常大,请输出此数模10007后的结果。

输入格式
第一行两个整数 为 n m

第二行 m个整数 ai

输出格式
此数模10007后的结果

输入输出样例

这里是引用

输入 #1

【样例输入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

【样例输出1】
20

【样例输出2】
8707

import java.util.*;

public class Main {

	public static void main(String[] args) {
		Main m = new Main();
		m.handleInput();
	}

	int n = 0, t = 0, m = 0, s = 1;
	int[][] a = new int[10010][105];
	int[] b = new int[1010];

	public void handleInput() {
		Scanner in = new Scanner(System.in);

		if (in.hasNext()) {
			n = in.nextInt();
			m = in.nextInt();
		}

		for (int i = 0; i <= n; i++) {
			a[i][0] = 1;
		}
		for (int i = 1; i <= Math.min(n, m); i++) {
			a[i][i] = 1;
		}
		for (int i = 1; i <= 10000; i++) {
			for (int j = 1; j <= Math.min(n, 100); j++) {
				a[i][j] = (a[i - 1][j - 1] + a[i - 1][j]) % 10007;
			}
		}
		for (int i = 1; i <= m; i++) {
			t = in.nextInt();
			s = s * a[n][t] % 10007;
			n -= t;
		}
		System.out.println(s);
	}

}

以前好像学过,忘了,记下,确实妙的方法,二维数组杨辉三角求组合数,a[i][j]=a[i-1][j-1]+a[i-1][j]
,,然后根据公式(ab)%p=((a%p)(b%p))%p就不用担心超int了

发布了88 篇原创文章 · 获赞 27 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_43457125/article/details/104507472