数学-满足条件的01序列-卡特兰数

C++

AcWing 889. 满足条件的01序列

/*
 *  问题描述:
 *      给定 n 个 0 和 n 个 1,它们将按照某种顺序排成长度为 2n 的序列,
 *      求它们能排列成的所有序列中,能够满足任意前缀序列中 0 的个数都不少于 1 的个数的序列有多少个。
 *      输出的答案对 109+7 取模。
 *      输入格式
 *      共一行,包含整数 n。
 *      输出格式
 *      共一行,包含一个整数,表示答案。
 *      数据范围
 *      1 ≤ n ≤ 10 ^ 5
 *
 *  解题思路:
 *      典型卡特兰数,
 *      组合数表示为:
 *          C(2n, n) - C(2n, n - 1)
 *              = C(2n, n - 1) / n
 *              = C(2n, n) / (n + 1)
 *      证明可以通过画图, y = x + 1 的对偶性来判断
 *          总方案为 C(2n, n)
 *          不合法方案为 C(2n, n - 1): 对偶得到
 *          因此,合法方案为 C(2n, n) - C(2n, n - 1)
 *
 */
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

typedef long long LL;
const int MOD = 1e9 + 7;

LL qmi(LL a, LL b, LL mod) {
    LL res = 1;
    while (b) {
        if (b & 1) {
            res = res * a  % mod;
        }
        b >>= 1;
        a = a * a % mod;
    }
    return res;
}

LL solution(int n) {
    // C(2n, n)
    LL res = 1;
    for (int i = 2 * n; i >= n + 1; i -- ) {
        res = res * i % MOD;
    }

    for (int i = 2; i <= n; i ++ ) {
        res = res * qmi(i, MOD - 2, MOD) % MOD;
    }

    res = res * qmi(n + 1, MOD - 2, MOD) % MOD;
    return res;
}

int main()
{
    int n;
    scanf("%d", &n);
    printf("%lld\n", solution(n));

    return 0;
}


posted @ 2022-07-27 22:51  lucky_light  阅读(98)  评论(0编辑  收藏  举报