[HAOI2009]逆序对数列
第一次我无脑敲了个生成排列+归并求逆序对。
十分。
然后发现就是很简单的递推。
因为是1~n的排列。
每次新加一个数 n+1,且新加的这个数是最大的,假设它放在第 i 位后,新生成的逆序对就是 n-i。
用 f[i][k] 表示1~i的排列中有k个逆序对的排列数。
f[i][k] = Σf[i-1][j] ( k-(i-1)<=j<=k ),新加一个数最多新产生 i-1 个逆序对。
为了不枚举j,可以用前缀和预处理,则复杂度为 O(n*m)。
// q.c #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; const int M=1000+10; const int mod=10000; int n,m,f[M][M],s[M]; int main() { freopen("permut.in","r",stdin); freopen("permut.out","w",stdout); scanf("%d%d",&n,&m); f[0][0]=1; f[1][0]=1; f[1][1]=0; for(int i=2;i<=n;i++) { s[0]=f[i-1][0]; for(int j=1;j<=m;j++) s[j]=(f[i-1][j]+s[j-1])%mod; for(int j=0;j<=m;j++) if(j-i>=0) f[i][j]=(s[j]-s[j-i]+mod)%mod; // 注意下标,Windows... else f[i][j]=s[j]%mod; } printf("%d\n",f[n][m]); return 0; }