【题解】逆序排列 [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]的更多相关文章
- 51nod 1020 逆序排列 DP
在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数. 如2 4 3 1中,2 1,4 3,4 1,3 1是逆序 ...
- 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 ...
- SQL-15 查找employees表所有emp_no为奇数,且last_name不为Mary的员工信息,并按照hire_date逆序排列
题目描述 查找employees表所有emp_no为奇数,且last_name不为Mary的员工信息,并按照hire_date逆序排列CREATE TABLE `employees` (`emp_no ...
- Java数组逆序排列
//逆序排列原理 /* A: 数组逆序原理* a: 题目分析* 通过观察发现,本题目要实现原数组元素倒序存放操作.即原数组存储元素为{12,69,852,25,89,588},逆序后为原数组存储元素变 ...
- 51nod 1020 逆序排列 递推DP
1020 逆序排列 基准时间限制:2 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 收藏 关注 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么 ...
- C语言 · 逆序排列
算法提高 逆序排列 时间限制:1.0s 内存限制:512.0MB 问题描述 编写一个程序,读入一组整数(不超过20个),并把它们保存在一个整型数组中.当用户输入0时,表示输入结束.然 ...
- 算法笔记_158:算法提高 逆序排列(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 编写一个程序,读入一组整数(不超过20个),并把它们保存在一个整型数组中.当用户输入0时,表示输入结束.然后程序将把这个数组中的值按逆序重新存 ...
- 51nod 1020 逆序排列——dp
在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数. 如2 4 3 1中,2 1,4 3,4 1,3 1是逆序 ...
- 1020 逆序排列(DP)
1020 逆序排列 基准时间限制:2 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序 ...
随机推荐
- Kubernetes概念之RC
感觉自己浪费了一年的时间,种一棵树最好的时间是十年前,还有就是现在,虽然这颗树种了又种,种了又种,这次真的要种了...... 本文通过<Kubernetes权威指南>的概念部分学习总结 ...
- 在知识爆炸的年代如何学习,避免成为PPT架构师
计算机的发展大体遵循摩尔定律,IT要学的东西越来越多,感觉无从下手 然后发现许多人,专门喜欢说这些名词概念装高大上,脱离一线开发,技术跟风盲目崇拜新的骚东西,比如docker,k8s,微服务,open ...
- flask 简单示例
flask import flask from flask import jsonify from flask import request # 要获取到请求参数的话,就要导入这个模块 ''' 创建接 ...
- nginx 跨域请求访问
1.nginx跨域请求访问 location ~ .*\.(htm|html)$ { add_header Access-Control-Allow-Origin(请求域名) *(所有域名) http ...
- 【大数据】0002---MongoDB集群自动分离创建新集群
场景:MongoDB集群运行后,自动产生新的集群 解答:可能没有理解问题,理清思路如下 1.日志分析 2.配置文件检查(日期.版本) 3.网络IP变化 4.github 5.stack overflo ...
- woocommerce隐藏breadcrumb面包屑导航
woocommerce已经集成比较完善的组件,当然也包含breadcrumb面包屑导航,但是我们如果调整一下breadcrumb的位置要如何操作呢?首先要先把woocommerce隐藏breadcru ...
- html--前端javascript初识
一.JavaScript简介 JavaScript是一种基于对象和事件驱动并具有安全性能的脚本语言,有了JavaScript,可使网页变得生动.使用它的目的是与HTML超文本标识语言.Java 脚本语 ...
- qhclass
http://www.qhclass.com/classroom/62/courses
- java 8 学习二(Lambda表达式)
粗略的概括:lambda表达式主要用来实现“函数接口”中“唯一”的抽象方法用的. 他的特殊版有 方法引用,构造函数引用,用对应的接口实例接收即可. 可以把Lambda表达式理解为简洁地表示可传递的匿名 ...
- 分布式环境配置虚拟域名,phpstudy配置虚拟域名,集成环境配置域名,域名禁止访问forbidden怎么解决
重启Apache,测试: