[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;
}

浙公网安备 33010602011771号