题目链接
也是简单的组合数学问题,每个位置可以移动走,也可以移动来,那么我们就需要找最终的状态,也就是最终的0的个数
假设有m个0,就有n-m个非0空位,选择0的组合数为( extrm{C}_{n}^{m}),这m个位置转移到n-m个位置的组合数为( extrm{D}_{n-m}^{m}),意思是从n-m个非0的部分选m个来接受这些转移来的,转换成组合数公式有:( extrm{D}_{n-m}^{m}) = ( extrm{C}_{n-1}^{n-m-1}),也就是说,x个中选y个,可以重复的组合数为( extrm{C}_{x+y-1}^{x-1})
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) ((x)&(-x))
typedef long long LL;
const int maxn = 2e5+5;
const LL MOD = 1e9+7;
LL F[maxn], Finv[maxn], inv[maxn];
void prework() {
inv[1] = 1;
for(int i = 2; i < maxn; ++i) {
inv[i] = (MOD - MOD / i) * 1LL * inv[MOD % i] % MOD;
}
F[0] = Finv[0] = 1;
for(int i = 1; i < maxn; ++i) {
F[i] = F[i-1] * 1LL * i % MOD;
Finv[i] = Finv[i-1] * 1LL * inv[i] % MOD;
}
}
LL comb(int n, int m) { //C(n, m)
if(n < m || m < 0) return 0;
return F[n] * 1LL * Finv[n-m] % MOD * Finv[m] % MOD;
}
void run_case() {
prework();
LL n, k, ans = 0;
cin >> n >> k;
for(int i = 0; i < n; ++i) {
if(i > k) break;
ans = (ans + comb(n, i) * comb(n-1, n-i-1)%MOD + MOD) % MOD;
}
cout << ans;
}
int main() {
ios::sync_with_stdio(false), cin.tie(0);
cout.flags(ios::fixed);cout.precision(10);
run_case();
cout.flush();
return 0;
}