【题解】逆序排列 [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\) 之后新构成的逆序对数 \(k\in [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\n",dp[n][K]);
}

【题解】逆序排列 [51nod1020]的更多相关文章

  1. 51nod 1020 逆序排列 DP

    在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数. 如2 4 3 1中,2 1,4 3,4 1,3 1是逆序 ...

  2. SQL-27 给出每个员工每年薪水涨幅超过5000的员工编号emp_no、薪水变更开始日期from_date以及薪水涨幅值salary_growth,并按照salary_growth逆序排列。 提示:在sqlite中获取datetime时间对应的年份函数为strftime('%Y', to_date)

    题目描述 给出每个员工每年薪水涨幅超过5000的员工编号emp_no.薪水变更开始日期from_date以及薪水涨幅值salary_growth,并按照salary_growth逆序排列. 提示:在s ...

  3. SQL-15 查找employees表所有emp_no为奇数,且last_name不为Mary的员工信息,并按照hire_date逆序排列

    题目描述 查找employees表所有emp_no为奇数,且last_name不为Mary的员工信息,并按照hire_date逆序排列CREATE TABLE `employees` (`emp_no ...

  4. Java数组逆序排列

    //逆序排列原理 /* A: 数组逆序原理* a: 题目分析* 通过观察发现,本题目要实现原数组元素倒序存放操作.即原数组存储元素为{12,69,852,25,89,588},逆序后为原数组存储元素变 ...

  5. 51nod 1020 逆序排列 递推DP

    1020 逆序排列  基准时间限制:2 秒 空间限制:131072 KB 分值: 80 难度:5级算法题  收藏  关注 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么 ...

  6. C语言 · 逆序排列

    算法提高 逆序排列   时间限制:1.0s   内存限制:512.0MB      问题描述 编写一个程序,读入一组整数(不超过20个),并把它们保存在一个整型数组中.当用户输入0时,表示输入结束.然 ...

  7. 算法笔记_158:算法提高 逆序排列(Java)

    目录 1 问题描述 2 解决方案 1 问题描述 问题描述 编写一个程序,读入一组整数(不超过20个),并把它们保存在一个整型数组中.当用户输入0时,表示输入结束.然后程序将把这个数组中的值按逆序重新存 ...

  8. 51nod 1020 逆序排列——dp

    在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数. 如2 4 3 1中,2 1,4 3,4 1,3 1是逆序 ...

  9. 1020 逆序排列(DP)

    1020 逆序排列 基准时间限制:2 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序 ...

随机推荐

  1. 人大金仓KCI

    #include "bin/libkci.h" static void exit_nicely(KCIConnection *conn) { KCIConnectionDestor ...

  2. 下载win10系统

    有时候想重装系统但总找不到下载的地方,今天记录一下.nsdn我告诉你,这里有许多软件下载 网站URL:https://msdn.itellyou.cn/ 我想下载一个Windows10 磁力地址 ed ...

  3. 并发编程(五)--GIL、死锁现象与递归锁、信号量、Event事件、线程queue

    一.GIL全局解释器锁 1.什么是全局解释器锁 GIL本质就是一把互斥锁,相当于执行权限,每个进程内都会存在一把GIL,同一进程内的多个线程,必须抢到GIL之后才能使用Cpython解释器来执行自己的 ...

  4. Nginx+Mysql调优

    使用nginx实现反向代理作用,具备负载均衡的功能.     接受客户端的请求 | nginx(宿主机) | |-------------------| web1 web2 (客户机)   原理: 与 ...

  5. Netty实战入门详解——让你彻底记住什么是Netty(看不懂你来找我)

    一.Netty 简介 Netty 是基于 Java NIO 的异步事件驱动的网络应用框架,使用 Netty 可以快速开发网络应用,Netty 提供了高层次的抽象来简化 TCP 和 UDP 服务器的编程 ...

  6. webUploader大文件断点续传学习心得 多文件

    二.Jsp代码: <!-- 断点续传   start--> <!-- 隐藏域 实时保存上传进度 --> <input id="jindutiao" t ...

  7. python 通过scapy获取网卡列表

    python通过scapy 获取网卡列表如下: #coding:utf-8 from scapy.all import * #显示网卡信息 show_interfaces() 运行结果如下:

  8. JDOJ 1606 数字三角形

    JDOJ 1606: 数字三角形 JDOJ传送门 Description 输入n,输出n的数字三角形 见样例 Input n Output n的数字三角形 Sample Input 4 Sample ...

  9. Java XML文档

    概念 XML(EXtensible Markup Language),可扩展标记语言.可扩展就是<>内的东西可以自己定义,可以随便写.标记语言就是加了<>符号的 .HTML是超 ...

  10. 蒟蒻所见之DP

    本文有错是正常的,因为这只是一部成长史,并非教学博文. 会常年更下去. 2019.10.24 DP,核心只是"表格法"而已. DP题真正所考察的,是: 1.对问题的描述.简化以及归 ...