BZOJ2431 HAOI2009逆序对数列(动态规划)
对于排列计数问题一般把数按一个特定的顺序加入排列。这个题做法比较显然,考虑将数从小到大加入排列即可。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; int read() { int x=0,f=1;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } #define N 1010 #define P 10000 int n,k,f[N][N]; void inc(int &x,int y){x+=y;if (x>=P) x-=P;} int main() { #ifndef ONLINE_JUDGE freopen("bzoj2431.in","r",stdin); freopen("bzoj2431.out","w",stdout); const char LL[]="%I64d\n"; #else const char LL[]="%lld\n"; #endif n=read(),k=read();if (!k) {cout<<1;return 0;} for (int j=0;j<=k;j++) f[0][j]=1; for (int i=1;i<=n;i++) { for (int j=0;j<=k;j++) inc(f[i][j],((j-i>=0?f[i-1][j]-f[i-1][j-i]:f[i-1][j])+P)%P); for (int j=1;j<=k;j++) inc(f[i][j],f[i][j-1]); } cout<<(f[n][k]-f[n][k-1]+P)%P; return 0; }