首页 > 代码库 > 诸城模拟赛 dvd的逆序对

诸城模拟赛 dvd的逆序对

【题目描述】

dvd是一个爱序列的孩子。

他对序列的热爱以至于他每天都在和序列度过

但是有一个问题他却一直没能解决

给你n,k1~n有多少排列有恰好k个逆序对

【输入格式】

一行两个整数n,k

【输出格式】

输出一个整数,表示答案对1000000007取模后的结果

【样例输入】

 4 1

【样例输出】

3

【样例解释】

1 2 4 3

1 3 2 4

2 1 3 4

【数据规模及约定】

对于10%的数据  n<=10

对于30%的数据  k<=50

对于100%的数据 1<=n,k<=1000 k<=n*(n-1)/2

 

/*当年的爆零题,今年的一眼题我们可以注意到,题目中要求的是这个方案数,而且这个数字很大,要对一个很大的数取模,考虑dp,f[i][j]表示1~j的排列恰好有i个逆序对,考虑f[i][j+1],等于是多了一个数字j+1,包括这个数字的逆序对是他后面的数的个数,剩下的逆序对就又前面j的排列来填补,这样维护一个前缀和,f[i][j] = f[i-j+1……i][j-1]*/#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<algorithm>using namespace std;const int maxn = 1050;const int mod = 1000000007;int n,k,f[maxn][maxn],s[maxn][maxn];int main(){    freopen("sequence.in","r",stdin);    freopen("sequence.out","w",stdout);    cin>>n>>k;    for(int i = 1;i <= n;i++) s[0][i] = f[0][i] = 1;    for(int i = 1;i <= k;i++){        for(int j = 1;j <= n;j++){            if(i >= j)f[i][j] = (s[i][j-1] - s[i-j][j-1] + mod) % mod;            else f[i][j] = s[i][j-1];            s[i][j] = (s[i-1][j] + f[i][j]) % mod;        }    }    cout<<f[k][n]<<endl;    return 0;}

 

 

 

诸城模拟赛 dvd的逆序对