[BZOJ2431] [HAOI2009]逆序对数列

Description

对于一个数列{ai},如果有i<j且ai>aj,那么我们称ai与aj为一对逆序对数。若对于任意一个由1~n自然数组成的
数列,可以很容易求出有多少个逆序对数。那么逆序对数为k的这样自然数数列到底有多少个?

Input

第一行为两个整数n,k。

Output

写入一个整数,表示符合条件的数列个数,由于这个数可能很大,你只需输出该数对10000求余数后的结果。

Sample Input

4 1

Sample Output

3

样例说明:
下列3个数列逆序对数都为1;分别是1 2 4 3 ;1 3 2 4 ;2 1 3 4;
100%的数据 n<=1000,k<=1000
 

 
本蒟蒻能写出来的题已经不多了...
这题也是其中的一个...
容易想到,一个序列,在其后面加一个数,产生的逆序对数量是前面大于它的数的个数。
那么我们设$large f[i][j]$,为填到了第i位,有j个逆序对的方案数。
因为要求答案是n的一个排列, 所以我们不妨假设前i个数正好是一个i+1排列中的i个,那么我们加入一个数k,会产生$i+1-k$个逆序对。
然后就这样递推。
不知为何$large O(N^3)$过了。
 

 
#include <iostream> 
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
#define reg register
#define mod 10000
int n, K;

int f[1005][1005];

int main()
{
    scanf("%d%d", &n, &K);
    f[0][0] = 1;
    for (reg int i = 0 ; i < n ; i ++)
        for (reg int j = 0 ; j <= K ; j ++)
            for (reg int k = 1 ; k <= i + 1 ; k ++) {
                if(j+i+1-k<=K)(f[i+1][j+(i+1-k)] += f[i][j]) %= mod;
            }
    cout << f[n][K] << endl;
    return 0;
}
原文地址:https://www.cnblogs.com/BriMon/p/9603305.html