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;    
}
posted @ 2016-06-16 11:20  invoid  阅读(117)  评论(0编辑  收藏  举报