加法原理
假设完成一件事的方法有
乘法原理
假设完成一件事需要
排列组合
排列
从
如何理解这个公式呢?
逐一考虑每个位置放置哪种元素,对于第一个位置,有
组合
从
如何理解这个公式呢?
如果从
组合数的一些性质:
组合数的求解方法:
方法一:根据公式直接计算。为了避免除法取模,可以通过计算分母的乘法逆元来计算。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, MOD = 1e9 + 7;
int fact[N], infact[N];
int qmi(int a, int b, int p) {
int ans = 1;
while (b) {
if (b & 1) ans = (long long)ans * a % p;
a = (long long)a * a % p;
b >>= 1;
}
return ans;
}
int main() {
fact[0] = infact[0] = 1;
for (int i = 1; i < N; i++) {
fact[i] = (long long)fact[i - 1] * i % MOD;
infact[i] = (long long)infact[i - 1] * qmi(i, MOD - 2, MOD) % MOD;
}
int T; cin >> T;
while (T--) {
int a, b; cin >> a >> b;
cout << (long long)fact[a] * infact[a - b] % MOD * infact[b] % MOD << endl;
}
return 0;
}方法二:根据性质
#include <bits/stdc++.h>
using namespace std;
const int N = 2010, MOD = 1e9 + 7;
int c[N][N];
int main() {
for (int i = 0; i < N; i++) {
for (int j = 0; j <= i; j++) {
if (!j) c[i][j] = 1;
else c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % MOD;
}
}
int T; cin >> T;
while (T--) {
int a, b; cin >> a >> b;
cout << c[a][b] << endl;
}
return 0;
}方法三:若题目中的
方法四:若题目中
组合与排列的关系
我们先从
特别的,当
排列组合的经典模型
- 捆绑法
假设有
- 隔板法
假设有
- 插空法
假设有
