zoukankan      html  css  js  c++  java
  • 51nod 1020

    求 $n$ 个数的排列中逆序数为 $k$ 的排列数
    $f[n][k]$ 表示 $n$ 个数的排列中逆序数为 $k$ 的排列数
    $f[n][k] = sum_{i = 0}^{n - 1} f[n - 1][k - i]$
    考虑当前 $n - 1$ 的排列中有 $k - i$ 个逆序对
    那么对于 $n$ 的排列,把最大数放到倒数第 $i$ 个数前,就会增加 $i$ 个逆序对
    同理 $f[n][k - 1] = sum_{i = 0} ^ {n - 1} f[n - 1][k - 1 - i]$
    两式相减

    egin{array}{l}
    f[n][k] - f[n][k - 1] \
    = sum_{i = 0}^{n - 1} f[n - 1][k - i] - sum_{i = 0} ^ {n - 1} f[n - 1][k - 1 - i] \
    = f[n - 1][k] - f[n - 1][k - n]
    end{array}

    then 地推公式为
    $f[n][k] = f[n][k - 1] + f[n - 1][k] - f[n - 1][k - n]$

    #include <bits/stdc++.h>
    
    #define gc getchar()
    
    inline int read() {
        int x = 0; char c = gc;
        while(c < '0' || c > '9') c = gc;
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc;
        return x;
    } 
    
    int f[(int)1e3 + 10][(int)1e3 + 10];
    const int Mod = 10000;
    
    void Work() {
        int n = (int)1e3;
        for(int i = 1; i <= n; i ++) f[i][0] = 1;
        for(int i = 2; i <= n; i ++) {
            for(int j = 1; j <= i * (i - 1) / 2 && j <= (int)1e3; j ++) {
                f[i][j] = (f[i][j] + f[i][j - 1] + f[i - 1][j]) % Mod;
                if(j - i >= 0) f[i][j] -= f[i - 1][j - i];
                f[i][j] = (f[i][j] + Mod) % Mod;
            }
        }
    }
    
    int main() {
        Work();
        int T = read();
        for(; T; T --) printf("%d
    ", f[read()][read()]);
        return 0;
    }
  • 相关阅读:
    大道至简读后感
    机器学习十讲(一)
    第一个TensorFlow的简单例子
    初识深度学习
    如何使用本地的Navicat连接服务器中的Mysql
    阿里云ECS-安装Tomcat
    阿里云ECS-CentOS 8上安装MySQL 8.0
    阿里云ECS--CentOS8安装jdk1.8
    进度报告十(重大技术需求)
    进度报告九 (重大技术需求调研)
  • 原文地址:https://www.cnblogs.com/shandongs1/p/9445249.html
Copyright © 2011-2022 走看看