在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。
如2 4 3 1中,2 1,4 3,4 1,3 1是逆序,逆序数是4。
1-n的全排列中,逆序数最小为0(正序),最大为n*(n-1) / 2(倒序)
给出2个数n和k,求1-n的全排列中,逆序数为k的排列有多少种?
例如:n = 4 k = 3。
1 2 3 4的排列中逆序为3的共有6个,分别是:
1 4 3 2
2 3 4 1
2 4 1 3
3 1 4 2
3 2 1 4
4 1 2 3
由于逆序排列的数量非常大,因此只需计算并输出该数 Mod 10^9 + 7的结果就可以了。
 
Input
第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 10000)
第2 - T + 1行:每行2个数n,k。中间用空格分隔。(2 <= n <= 1000, 0 <= k <= 20000)
Output
共T行,对应逆序排列的数量 Mod (10^9 + 7)
Input示例
1
4 3
Output示例
6
相关问题

思路:

设dp[i][j]表示1-i的全排列中逆序数为j的个数。试想,假如一直dp[i-1]的每一种状态,那么和dp[i]有什么关系。

不难得出,对于已知的dp[i-1]的基础上,插入i就可以得到dp[i]。但是i的位置放置的不同,就影响了dp[i]的每一项。

列出i取值1,2,3,4的每一项,可以得出一个关系式:

得到这个关系式其实这道题目已经可以做了,利用前缀和优化,但是还可以更进一步

同理有:

此时假设k可以取到0,实际上max在这里只是优化

则可以得到:

最后需要注意相减可能为负数,需要加上mod再取mod

代码:

 #include <stdio.h>
const int mod=;
int dp[][];
void init() {
for(int i=;i<=;++i) {
dp[i][]=;
}
for(int i=;i<=;++i) {
int maxval=i*(i-)>>;
for(int j=;j<=maxval&&j<=;++j) {
int temp=;
if(j>=i) temp=dp[i-][j-i];
dp[i][j]=((dp[i][j-]+dp[i-][j]-temp)%mod+mod)%mod;
}
}
}
int main() {
init();
int T,n,k;
scanf("%d",&T);
while(T--) {
scanf("%d %d",&n,&k);
printf("%d\n",dp[n][k]);
}
return ;
}

51nod 1020 逆序排列 DP的更多相关文章

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

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

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

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

  3. 1020 逆序排列(DP)

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

  4. 51nod 1020 逆序排列(dp,递推)

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1020 题意:是中文题. 题解:很显然要设dp[i][j]表示 ...

  5. 51nod 1020 逆序排列

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1020 题意: 思路: 一开始用了三重循环... 设f(n,k)表示n个数 ...

  6. 51 Nod 1020 逆序排列

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

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

    [题解]逆序排列 [51nod1020] 传送门:逆序排列 \([51nod1020]\) [题目描述] 共 \(T\) 组测试点,每一组给出 \(2\) 个整数 \(n\) 和 \(k\),在 \( ...

  8. 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 ...

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

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

随机推荐

  1. Memcached理解

    一.Memcached简介: 1. Memcached是一个自由开源的,高性能的,分布式内存对象缓存系统. 2. Memcached是一种基于内存的key-value存储,用来存储小块的任意数据(字符 ...

  2. C++实现引用和被引用对象分离

    上一篇博客简单介绍了C++中引用的底层实现,接下来,通过简单的代码验证如何将引用和被引用对象分离. 代码如下; #include <iostream> #include<string ...

  3. 面试题----寻找比一个N位数大的“下”一个数

    题目描述 写出一个算法,实现如下功能: 给定一个N位数字组成的数,找出比这个数大的由相同数字组成的下一个数 例如:如果数字为 25468, 则结果为25486 如果数字为 21765, 则结果为 25 ...

  4. 暑假练习赛 003 B Chris and Road

    B - Chris and Road Crawling in process... Crawling failed Time Limit:2000MS     Memory Limit:262144K ...

  5. two.js之实现动画效果

    一.什么是two.js? Two.js 是面向现代 Web 浏览器的一个二维绘图 API.Two.js 可以用于多个场合:SVG,Canvas 和 WebGL,旨在使平面形状和动画的创建更方便,更简洁 ...

  6. 从Matlab文件中读取mxArray类型变量-部分代码分析

    这是我做的笔记,看到这个代码时觉得处理有点妙,做笔记记录之. 部分源代码: .... int main(int argc,char** argv) { char name[_FILE_NAME_LEN ...

  7. html的块级元素和内联元素

    常用的块级元素: address , center , div , dl ,, form , h1 , h2 , h3 , h4 , h5 , h6 , menu , ol , p , table , ...

  8. ECMAScript 6 proxies

    在ECMAScript 5里面,可以通过(writable 和 configurable)内部属性把属性设置为不可修改和不可删除的,可以通过(Object.preventExtensions() )让 ...

  9. 微服务下的契约测试(CDC)解读

    1. 前言 有近两周没有在公众号中发表文章了,看过我之前公众号的读者都知道,公众号中近期在连载<RobotFramework接口自动化系列课程>,原本计划每周更新一篇,最近由于博主在带一个 ...

  10. winscp连接虚拟机Linux被拒绝的问题解决方案

    输入了正确的账号密码还出现这个错误 我们需要在虚拟机中配置一下,改成这样就行了