题意:
逆序对指在一个序列中ai>aj && i < j,也就是一前一后两个数,当大的在前面的时候即算一对。

题目求在一个由1…n组成的序列中逆序对为k的序列的个数。
出题人很良心,不需要写高精度,答案对10000取模即可。

思路:
这道题的前面其实还有一道很类似的题,也是求逆序对。不同的是那道题给定了序列求逆序对的个数,而这道题则相反。那道题的方法即merge sort。尽管两题很类似,但是方法却截然不同。

凭感觉,这应该是一道动规的题。长度为n-1的序列与长度为n的序列只差一个n,而由于n出现的逆序对也很好求:n在第i个就会相比于原序列多出n-i个逆序对。如此,那看来是动规无疑了。

状态转移方程:若长度为n的序列要求有k个逆序对,那么他可以从长为n-1的序列中选取有k-n+1到k个逆序对的部分。道理很简单n的加入最多使原序列增加n-1个逆序对(即放在第一个的时候,与后面n-1个数构成逆序对),所以要从x[n-I][p]变到x[n][k],p属于[k-n+1,k]。那么转移方程式就很好写了:

for(unsigned i = 2; i != n+1; ++i)
{
dp[i][0] = 1;
for(unsigned j = 1; j != k+1; ++j)
{
for(unsigned p = k-j+1; p != j+1; ++p)
{
dp[i][j] += dp[i-1][p];
}
}
}

优化:
这是一个O(n^3)的算法,很慢。我们观察最内层循环,发现它很多余,因为总是重复操作。dp[i][j-1]和dp[i][j]当i-j+1>0的时候,中间部分完全相同,只是掐头增尾的问题。由此我们可以有第一种优化:dp[i][j] = dp[i][j-1]-dp[i-1][j-i]+dp[i-1][j];(j-i >-1)

当然也可以直接采用前缀数组和的方式将这段循环优化掉,到O(n^2)。
(后面的代码采取的是这一种)

源代码的读入是多组数据。


源代码:

#include <bits/stdc++.h>
#define maxn 1005
#define mod 10000
//#define DEBUG
#ifdef DEBUG
#define debug(...)printf(__VA_ARGS__);
#else
#define debug(...)
#endif
using namespace std; int n[15], k[15], dp[maxn][maxn*10]; void Dp(int n, int k)
{
int a;
memset(dp, 0, sizeof dp);
for(unsigned i = 0; i != k+1; ++i)
{
dp[1][i] = 1;
}
for(int i = 2; i != n+1; ++i)
{
dp[i][0] = 1;
for(int j = 1; j != k+1; ++j)
{
if(j-i > -1) a = dp[i-1][j-i];
else a = 0;
dp[i][j] = (dp[i][j-1]+dp[i-1][j]-a+mod)%mod;
debug("%d ", dp[i][j]);
}
debug("\n");
}
return ;
} int main()
{
//freopen("test.in", "r", stdin);
int times, Maxn = 0, Maxk = 0;
scanf("%d", &times);
for(unsigned i = 0; i != times; ++i)
{
scanf("%d%d", &n[i], &k[i]);
Maxn = max(Maxn, n[i]);
Maxk = max(Maxk, k[i]);
}
Dp(Maxn, Maxk);
for(unsigned i = 0; i != times; ++i)
{
printf("%d\n", (mod+dp[n[i][k[i]]-dp[n[i]][k[i]-1])%mod);
}
return 0;
}

箜瑟_qi 2017.04.27 15:01

luogu 1521-求逆序对的更多相关文章

  1. 2021.12.10 P5041 [HAOI2009]求回文串(树状数组求逆序对)

    2021.12.10 P5041 [HAOI2009]求回文串(树状数组求逆序对) https://www.luogu.com.cn/problem/P5041 题意: 给一个字符串 \(S\) ,每 ...

  2. HDU 3743 Frosh Week(归并排序求逆序对)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3743 题目意思就是给你一个长为n的序列,让你求逆序对.我用的是归并排序来求的.归并排序有一个合并的过程 ...

  3. AC日记——codevs 1688 求逆序对

    1688 求逆序对  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description 给定一个序列a1,a2,…, ...

  4. POJ2299Ultra-QuickSort(归并排序 + 树状数组求逆序对)

    树状数组求逆序对   转载http://www.cnblogs.com/shenshuyang/archive/2012/07/14/2591859.html 转载: 树状数组,具体的说是 离散化+树 ...

  5. codevs1688 求逆序对

    题目描述 Description 给定一个序列a1,a2,…,an,如果存在i<j并且ai>aj,那么我们称之为逆序对,求逆序对的数目 数据范围:N<=105.Ai<=105. ...

  6. HDU 4911 http://acm.hdu.edu.cn/showproblem.php?pid=4911(线段树求逆序对)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4911 解题报告: 给出一个长度为n的序列,然后给出一个k,要你求最多做k次相邻的数字交换后,逆序数最少 ...

  7. SGU 180 Inversions(离散化 + 线段树求逆序对)

    题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=180 解题报告:一个裸的求逆序对的题,离散化+线段树,也可以用离散化+树状数组.因为 ...

  8. 树状数组求逆序对:POJ 2299、3067

    前几天开始看树状数组了,然后开始找题来刷. 首先是 POJ 2299 Ultra-QuickSort: http://poj.org/problem?id=2299 这题是指给你一个无序序列,只能交换 ...

  9. wikioi 1688 求逆序对

    /*=========================================================== wikioi 1688 求逆序对 时间限制: 1 s 空间限制: 12800 ...

  10. 【剑指offer】求逆序对的个数

    2013-09-07 10:50:31 面试题36:在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字构成一个逆序对.输入一个数组,求出这个数组中逆序对的总数. 小结: 最直观的的方法是: ...

随机推荐

  1. Linux中的sed命令

    sed - stream editor for filtering and transforming text 流编辑器的过滤和转换文本 sed [-nerf] [动作] 参数: -i 修改源文件 危 ...

  2. Linux下安装Java(JDK8)

    一.文件准备 1.1 文件名称 jdk-8u121-linux-x64.tar.gz 1.2 下载地址 http://www.oracle.com/technetwork/java/javase/do ...

  3. Java结合WebUploader文件上传

    之前自己写小项目的时候也碰到过文件上传的问题,没有找到很好的解决方案.虽然之前网找各种解决方案的时候也看到过WebUploader,但没有进一步深究.这次稍微深入了解了些,这里也做个小结. 简单的文件 ...

  4. Appium 解决手势密码 java

    if(driver.getPageSource().contains("绘制解锁图案")){//检测是否是有手势密码出现 List<AndroidElement> el ...

  5. Ubuntu 16.04 设置MySQL远程访问权限

    本文记录一下在Ubuntu 16.04版本下设置MySQL数据库的远程访问. 第一步:修改配置文件的端口绑定 打开的目录可能会根据MySQL的版本稍有不同,可以先尝试打开/etc/mysql/my.c ...

  6. js 操作 cookie

    js 操作 cookie 的方法如下: //设置cookie function setCookie(cname, cvalue, exdays) { var d = new Date(); d.set ...

  7. 在app中屏蔽第三方键盘

    iOS8开放了安装第三方键盘的权限,但是在项目开发中,有些情况是需要禁用第三方键盘的.比如说,数字键盘上需要自定义按钮,但是在第三方键盘弹出时,按钮就覆盖在这上面了,在这中情况下,最好的办法是禁用第三 ...

  8. 打造比Dictionary还要快2倍以上的字查找类

    针对一个长度为n的数组. [1,2,3,4,5,6,7,8,9] 最快的通用查找类是Dictionary其采用hashcode算法,复杂度为O(1). 而上大学时,最快的查找法为二分查找法,复杂度为O ...

  9. webx request注入单例增强实现

    由于在spring中request对象的scope限制导致了request对象无法直接注入到单例bean中,所以webx对其进行了增强实现,达到单例注入的目的. 实现原理大致如下: 1 启动时注册全局 ...

  10. 编译MangosZero

    最近研究了一下魔兽世界模拟器MangosZero,花了两天时间终于编译成功!现在把编译的过程做个完整的记录,以便让想要学习编译的同学们少走弯路! 服务器端运行界面: 客户端运行界面: 一:下载源程序 ...