题目
给定 组询问,每组询问给定两个整数 ,请你输出 的值。
输入格式
第一行包含整数 。
接下来 行,每行包含一组 和 。
输出格式
共 行,每行输出一个询问的解。
数据范围
,
输入样例:
3
3 1
5 3
2 2
输出样例:
3
10
1
解题
方法一:递推
思路
本题询问比较多,如果对每组询问直接用公式 求组合数的话,时间复杂度最差会到 显然会超时。
但是本题 的取值范围都比较小,为 ,所以我们可以预处理 的所有组合数。
组合数递推式: 。
证明:
在 个物品中选择 个物品( ),假如当前拿出来了一个物品:
- 如果该物品不在要选择的 个物品中,那么我们还需要在 个物品中选择 个物品( );
- 如果该物品在要选择的 个物品中,那么我们还需要在 个物品中选择 个物品( )。
综上, 成立。
时间复杂度:
代码
import java.util.*;
import java.io.*;
public class Main {
static final int N = 2000, MOD = (int) 1e9 + 7;
static int[][] c = new int[N + 1][N + 1];
static {
for (int n = 0; n <= N; ++n) {
for (int m = 0; m <= n; ++m) {
if (m == 0) c[n][m] = 1;
else c[n][m] = (c[n - 1][m] + c[n - 1][m - 1]) % MOD;
}
}
}
public static void main(String[] args) throws IOException {
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
in.nextToken();
int n = (int) in.nval;
while (n-- > 0) {
in.nextToken();
int a = (int) in.nval;
in.nextToken();
int b = (int) in.nval;
System.out.println(c[a][b]);
}
}
}
评论区