bzoj2431: [HAOI2009]逆序对数列
dp.
f[i][j]表示放置第i个数有j个逆序对的方案数。 s[i][j]维护前缀和(f[i][0]~f[i][j])。
状态转移方程 f[i][j]=s[i-1][j]-s[i-1][max(j-1,0)]。
oi界十大水题。
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int mod = 10000; const int maxn = 1000 + 10; int f[maxn][maxn],s[maxn][maxn]; int n,k; int main() { scanf("%d%d",&n,&k); memset(f,0,sizeof(f)); memset(s,0,sizeof(s)); f[1][0]=1; for(int i=0;i<=k;i++) s[0][i]=1; for(int i=1;i<=n;i++) { s[i][0]=f[i][0]=s[i-1][0]; for(int j=1;j<=(i-1);j++) { f[i][j]=s[i-1][j]; s[i][j]=(f[i][j]+s[i][j-1])%mod; } for(int j=i;j<=k;j++) { f[i][j]=(s[i-1][j]-s[i-1][j-i]+mod)%mod; s[i][j]=(f[i][j]+s[i][j-1])%mod; } } printf("%d\n",f[n][k]); return 0; }