ABC156E

题目链接
也是简单的组合数学问题,每个位置可以移动走,也可以移动来,那么我们就需要找最终的状态,也就是最终的0的个数
假设有m个0,就有n-m个非0空位,选择0的组合数为\(\textrm{C}_{n}^{m}\),这m个位置转移到n-m个位置的组合数为\(\textrm{D}_{n-m}^{m}\),意思是从n-m个非0的部分选m个来接受这些转移来的,转换成组合数公式有:\(\textrm{D}_{n-m}^{m}\) = \(\textrm{C}_{n-1}^{n-m-1}\),也就是说,x个中选y个,可以重复的组合数为\(\textrm{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;
}

猜你喜欢

转载自www.cnblogs.com/GRedComeT/p/12358749.html
156
今日推荐