• [SDOI2016]排列计数(组合计数)


    题意:

    求有多少种 $1$ 到 $n$ 的排列 $a$,满足序列恰好有 $m$ 个位置 $i$,使得 $a_i = i$

    题解:

    这就是个普通的部分错排问题。

    因为要选 $m$ 个位置不是错排,共有$C_n^m$中选择。剩下的必须是完全错排。设$n$个数完全错排的方案数是$f_n$。则答案为$C_n^m imes f_{n-m}$。

    怎么求f?

    其实有一个递推式$f_i=(i-1) imes (f_{i-1}+f_{i-2})$。

    考虑把第i个数放在前i-1个位置中的任意一个位置k,共有i-1中放法。

    原本在第k个位置的数如果到了i,则剩下的i-2个数构成一个错排问题,乘上$f_{i-2}$即可。第k个位置的数不到i,则剩下i-1个数构成一个错排问题乘上$f_{i-1}$。

    #include <iostream>
    #include <cstdio>
    using namespace std;
    typedef long long ll;
    const ll MOD = 1e9 + 7;
    template <typename T> void read(T &x) {
        T ff = 1; char ch = getchar(); x = 0;
        for (; !isdigit(ch); ch = getchar()) if (ch == '-') ff = -1;
        for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
        x *= ff;
    }
    template <typename T> void write(T x) {
        if (x > 9) write(x / 10);
        putchar(x % 10 + '0');
    }
    template <typename T> void print(T x) {
        if (x < 0) x = -x, putchar('-');
        write(x);
        putchar('
    ');
    }
    ll ksm(ll a, ll b, ll m) {
        ll ret = 1;
        while (b) {
            if (b & 1) ret = (ret * a) % m;
            a = (a * a) % m;
            b >>= 1;
        }
        return ret;
    }
    ll f[1000010], g[1000010];
    ll n, m, t;
    ll C(ll i, ll j) {
        return (((g[i] * ksm(g[j], MOD - 2, MOD)) % MOD) * ksm(g[i - j], MOD - 2, MOD)) % MOD;
    }
    int main() {
        read(t);
        g[0] = 1; g[1] = 1; g[2] = 2; f[1] = 0; f[2] = 1;
        for (int i = 3; i <= 1000000; i++) {
            f[i] = ((i - 1) * (f[i - 1] + f[i - 2])) % MOD;
            g[i] = (g[i - 1] * i) % MOD;
        }
        while (t--) {
            read(n); read(m);
            if (n == m) print(1);
            else print((C(n, m) * f[n - m]) % MOD);
        }
        return 0;
    }
  • 相关阅读:
    kafka环境搭建
    zookeeper环境搭建学习
    linux时间不准
    (转)Mac osx 下安装iTerm2,并使用rz sz上传下载(附homebrew配置)
    安装mariadb数据库
    mydumper 安装使用
    granfa 安装,配置prometheus数据源
    prometheus 普罗米修斯安装
    Docker常用命令
    winform 一个点击事件触发另一个点击事件
  • 原文地址:https://www.cnblogs.com/zcr-blog/p/13149598.html
Copyright © 2020-2023  润新知