题目大意

在一个长度为 nn 的排列中找出逆序对数量恰好为 cc 的排列总数,其中 1n103,1c1041\le n \le 10^3,1\le c \le 10^4

思路

考虑将 11nn 这些数从小到大一次填进去,因为每一次填入的数多是最大的,所以逆序对增加的数量只与其所在的位置相关,所以设计 fi,jf_{i,j} 表示前 ii 个数逆序对为 jj 的方案数。

在填入第 ii 个数时因为前面的 11i1i-1 都小于 ii,所以 ii 每向前移动一个位置,逆序对的数量就会增加 11

因为 ii 的位置并没有限制,所以 fi,j=k=0i1fi1,jkf_{i,j}=\sum \limits^{i-1}\limits_{k=0} f_{i-1,j-k}

这个方法的时间复杂度与空间复杂度都是 O(n×c2)O(n\times c^2) 的,无法通过此题,所以可以使用前缀和与滚动数组优化。

AC Code

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e4+5,mod=1e9+7;
int n,c,f[N],ans;
signed main(){
    cin>>n>>c;
	f[0]=1;
    for(int i=1;i<=n;i++){
    	for(int j=1;j<=c;j++) f[j]=(f[j]+f[j-1])%mod;
        for(int j=c;j>=i;j--){
            f[j]=(f[j]-f[j-i]+mod)%mod;
        }
    }cout<<f[c]<<endl;
    return 0;
}