[HAOI2009]逆序對數列
阿新 • • 發佈:2018-11-22
Description
對於一個數列{ai},如果有i
Input
第一行為兩個整數n,k。
Output
寫入一個整數,表示符合條件的數列個數,由於這個數可能很大,你只需輸出該數對10000求餘數後的結果。
Sample Input
4 1
Sample Output
3
HINT
100%的資料 n<=1000,k<=1000
二維dp
設f[i][j]表示列舉到第i個點,逆序對個數為j的方案數,利用字首和優化可以將複雜度降到\(O(n^2)\)
/*program from Wolfycz*/ #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define inf 0x7f7f7f7f using namespace std; typedef long long ll; typedef unsigned int ui; typedef unsigned long long ull; inline char gc(){ static char buf[1000000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++; } inline int frd(){ int x=0,f=1; char ch=gc(); for (;ch<'0'||ch>'9';ch=gc()) if (ch=='-') f=-1; for (;ch>='0'&&ch<='9';ch=gc()) x=(x<<3)+(x<<1)+ch-'0'; return x*f; } inline int read(){ int x=0,f=1; char ch=getchar(); for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1; for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+ch-'0'; return x*f; } inline void print(int x){ if (x<0) putchar('-'),x=-x; if (x>9) print(x/10); putchar(x%10+'0'); } const int N=1e3,p=1e4; int f[N+10][N+10],g[N+10][N+10]; int main(){ int n=read(),k=read(); f[1][0]=1; for (int i=0;i<=k;i++) g[1][i]=1; for (int i=2;i<=n;i++){ for (int j=0;j<=k;j++) if (j<i) f[i][j]=g[i-1][j]; else f[i][j]=(g[i-1][j]-g[i-1][j-i]+p)%p; g[i][0]=f[i][0]; for (int j=1;j<=k;j++) g[i][j]=(g[i][j-1]+f[i][j])%p; } printf("%d\n",f[n][k]); }