zoukankan      html  css  js  c++  java
  • 【题解】逆序排列 [51nod1020]

    【题解】逆序排列 [51nod1020]

    传送门:逆序排列 ([51nod1020])

    【题目描述】

    (T) 组测试点,每一组给出 (2) 个整数 (n)(k),在 ([1,n])(n) 个数字的全排列中,逆序数为 (k) 的排列种数,答案对 (1e9+7) 取模。

    【样例】

    样例输入:
    1
    4 3
    
    样例输出:
    6
    

    【数据范围】

    (100\%) (1 leqslant T leqslant 10000,) (1 leqslant N leqslant 1000,) (1 leqslant K leqslant 20000)

    【分析】

    (dp[i][j]) 表示 ([1,i]) 的排列中逆序对数为 (j) 的排列种数,为方便枚举,用 (ss[i]) 表示长度为 (i) 的排列总数((ss[i]=min{K,frac{i*(i-1)}{2}})

    对于数字 (i) 来说,在一个 ([1,i-1]) 的排列中它有 (i) 个位置可以加入,加下 (i) 之后新构成的逆序对数 (kin [0,i-1])
    那么 (dp) 方程就出来了:(dp[i][j]+=dp[i-1][j-k]),其中 (0 leqslant j leqslant ss[i],) (0 leqslant j-k leqslant ss[i-1]) ,所以 (max{0,j-ss[i-1]} leqslant k leqslant min{j,i-1})
    (dp[i][j]=sum_{k=max{0,j-ss[i-1]}}^{min{j,i-1}}dp[i-1][j-k])

    时间复杂度过高,要用前缀和优化一下,(dp[i][j]=S[j-max(0,j-ss[i-1])]-S[j-min(i-1,j)-1]),其中 (S[i]=sum_{j=0}^{i}dp[i-1][j])

    但是前缀和下边界可能会取到 (0),减了 (1) 之后就成了 (-1)(S[-1])是不存在的,所以每一次写 (S[x]) 都要改成 (S[x+1])

    还要先预处理答案,询问时直接 (O(1)) 查询。

    时间复杂度为 (O(NK))

    【Code】

    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #define LL long long
    #define Re register int
    using namespace std;
    const int N=1003,M=2e4+3,P=1e9+7;
    int T,n,K,S[M],ss[N],dp[N][M];
    inline void in(Re &x){
        int f=0;x=0;char c=getchar();
        while(c<'0'||c>'9')f|=c=='-',c=getchar();
        while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
        x=f?-x:x;
    }
    int main(){
        n=1000,K=20000;
        for(Re i=2;i<=n;++i){
        	ss[i]=i*(i-1)>>1;
        	if(ss[i]>K){for(Re j=i;j<=n;++j)ss[j]=K;break;}
        }
        for(Re i=1;i<=n;++i)dp[i][0]=1;
        for(Re j=0;j<=ss[2];++j)(S[j+1]=S[j-1+1]+dp[1][j])%=P;
        for(Re i=2;i<=n;++i){
        	for(Re j=1;j<=ss[i];++j)(dp[i][j]=(S[j-max(0,j-ss[i-1])+1]-S[j-min(i-1,j)-1+1]+P)%P)%=P;
        	for(Re j=0;j<=ss[i+1];++j)(S[j+1]=S[j-1+1]+dp[i][j])%=P;
        }
        in(T);while(T--)in(n),in(K),printf("%d
    ",dp[n][K]);
    }
    
  • 相关阅读:
    将字符串数组转换成整形数组
    层的三级联动
    sql
    工作中的感悟
    asp.net如何抓取其他网站的内容
    看不到的SQl
    对数据库中时间为空的处理和数据转换成百分数
    不带查询条件的分页
    svn中出现红色感叹号
    视图的创建(根据已有的表)
  • 原文地址:https://www.cnblogs.com/Xing-Ling/p/11347772.html
Copyright © 2011-2022 走看看