转自YXDs

题目传送门
不知道今天是怎么了,可能是空调吹多了吧,一直不在状态,连递推题我都做不来了……(扎Zn了老Fe……)
然而,不管环境如何恶劣,我们仍要努力学习,为了自己的明天而奋斗。(说的好像跟真的一样)
其实这题就是一个递推,现在我们考虑第i个数,定义f[i][j]表示序列里有i个数,逆序对的组数为j的方案数。
因为第i个数的权值就是i,则不管第i个数插到序列里的哪个位置,都会和在它后面的数形成逆序对,因此第i个数插到序列里最多形成i-1个逆序对,最少形成0个。
所以,我们就得到了递推公式:f[i][j]=Σf[i-1][j-k] (j-i+1<=k<=j)
但是现在的时间复杂度仍然是O(n^3)的,n的范围是1000,铁定TLE。
但是看到上面的递推式中有Σ,于是我们就想到了前缀和,降掉一维的复杂度,过掉这道题非常轻松。
另外,由递推式可发现,第i个数的所有逆序对方案数都只跟第i-1个数的逆序对方案数有关,因此可以使用滚动数组来存储,减少内存的使用。
(虽然在这题里并没有什么卵用,在BZOJ上实测出来大概省了80+kb的空间吧……)
注意:本题需要考虑中途答案为负的情况,虽然只要加上p就行了,但是一定要注意考虑,别忘了。
O(n^3)算法(主要是怕自己会忘):

#include <cstdio>
#define p 10000
using namespace std; int n,m,f[][]; int main(void){
scanf("%d%d",&n,&m);
for (int i=; i<=n; ++i) f[i][]=;
for (int i=; i<=n; ++i)
for (int j=; j<=m; ++j)
for (int k=; k<=j&&k<i; ++k)
f[i][j]=(f[i][j]+f[i-][j-k])%p;
printf("%d",f[n][m]);
return ;
}

N^3

O(n^2)算法(AC代码):

#include <cstdio>
#define p 10000
using namespace std; int n,m,f[],c[]; int main(void){
scanf("%d%d",&n,&m);
f[]=;
for (int i=; i<=n; ++i){
for (int j=; j<=m; ++j) c[j]=(c[j-]+f[j])%p;
for (int j=; j<=m; ++j)
if (j>) if (j>=i) f[j]=(c[j]-c[j-i]+p)%p;
else f[j]=c[j];
else f[j]=;
}
printf("%d",f[m]);
return ;
}

AC

附:公式改进法,我在洛谷上看见的。
由上面的那个递推公式可知:f[i][j]=f[i-1][j]+f[i-1][j-1]+…+f[i-1][j-i+1]
又f[i][j-1]=f[i-1][j-1]+f[i-1][j-2]+…+f[i-1][j-i]
所以f[i][j]=f[i-1][j]+f[i][j-1]-f[i-1][j-i]
虽然这个公式的变形在这题中并没有什么特别大的用处,但是这种思想是非常好的,常常可以把一些非常复杂的公式变得简单些,公式的特点也更明显一些。
所以我们还是有必要学习一下这种思想的。
然后就是递推了,其他都和上面的代码差不多的。

#include <cstdio>
#define p 10000
using namespace std; int n,m,f[][]; int main(void){
scanf("%d%d",&n,&m);
f[][]=;
for (int i=; i<=n; ++i)
for (int j=; j<=m; ++j)
if (j>) if (j>=i) f[i%][j]=(f[(i-)%][j]+f[i%][j-]-f[(i-)%][j-i]+p)%p;
else f[i%][j]=(f[(i-)%][j]+f[i%][j-])%p;
else f[i%][j]=(f[(i-)%][j])%p;
printf("%d",f[n%][m]>?f[n%][m]:-);
return ;
}

AC-公式改进法

BZOJ2431_逆序对数列_KEY的更多相关文章

  1. bzoj2431:[HAOI2009]逆序对数列

    单组数据比51nod的那道题还弱...而且连优化都不用了.. #include<cstdio> #include<cstring> #include<cctype> ...

  2. BZOJ 2431: [HAOI2009]逆序对数列( dp )

    dp(i,j)表示1~i的全部排列中逆序对数为j的个数. 从1~i-1的全部排列中加入i, 那么可以产生的逆序对数为0~i-1, 所以 dp(i,j) = Σ dp(i-1,k) (j-i+1 ≤ k ...

  3. 2431: [HAOI2009]逆序对数列

    2431: [HAOI2009]逆序对数列 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 954  Solved: 548[Submit][Status ...

  4. 【BZOJ2431】逆序对数列(动态规划)

    [BZOJ2431]逆序对数列(动态规划) 题面 Description 对于一个数列{ai},如果有i<j且ai>aj,那么我们称ai与aj为一对逆序对数.若对于任意一个由1~n自然数组 ...

  5. P2513 [HAOI2009]逆序对数列

    P2513 [HAOI2009]逆序对数列 题目描述 对于一个数列{ai},如果有iaj,那么我们称ai与aj为一对逆序对数.若对于任意一个由1~n自然数组成的数列,可以很容易求出有多少个逆序对数.那 ...

  6. bzoj千题计划153:bzoj2431: [HAOI2009]逆序对数列

    http://www.lydsy.com/JudgeOnline/problem.php?id=2431 dp[i][j] 表示i的排列,有j个逆序对的方案数 加入i+1,此时i+1是排列中最大的数, ...

  7. BZOJ2431 HAOI2009 逆序对数列 【DP】*

    BZOJ2431 HAOI2009 逆序对数列 Description 对于一个数列ai{a_i}ai​,如果有i<j且ai>aja_i>a_jai​>aj​,那么我们称aia ...

  8. 洛谷P2513 [HAOI2009]逆序对数列

    P2513 [HAOI2009]逆序对数列 题目描述 对于一个数列{ai},如果有i<j且ai>aj,那么我们称ai与aj为一对逆序对数.若对于任意一个由1~n自然数组成的数列,可以很容易 ...

  9. bzoj2431: [HAOI2009]逆序对数列(前缀和优化dp)

    2431: [HAOI2009]逆序对数列 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 2312  Solved: 1330[Submit][Stat ...

随机推荐

  1. jumpserver V0.4.0 在CentOs7上的安装

    基于 CentOS 7 一步一步安装 Jumpserver 0.4.0 环境 系统: CentOS 7 IP: 192.168.226.128 一. 准备Python3和Python虚拟环境 1.1 ...

  2. js中匿名函数

    今天碰到一道题,里面既包含了匿名函数的知识,也包含了预编译,函数的传参(形参),感觉迷迷糊糊的,所以想着做个总结. var foo={n:1}; (function(foo){ console.log ...

  3. 转每天一个linux命令(3):pwd命令

    Linux中用 pwd 命令来查看"当前工作目录"的完整路径. 简单得说,每当你在终端进行操作时,你都会有一个当前工作目录. 在不太确定当前位置时,就会使用pwd来判定当前目录在文 ...

  4. 拨开字符编码的迷雾--MySQL数据库字符编码

    拨开字符编码迷雾系列文章链接: 拨开字符编码的迷雾--字符编码概述 拨开字符编码的迷雾--编译器如何处理文件编码 拨开字符编码的迷雾--字符编码转换 拨开字符编码的迷雾--MySQL数据库字符编码 1 ...

  5. Keil报错failed to execute 'd:\Keil\C51\BIN\C51.EXE'

    关于老师发的keil软件报错如下: --- Error: failed to execute 'd:\Keil\C51\BIN\C51.EXE' 错误是因为老师直接拷贝的安装目录,里面的文件路径设置仍 ...

  6. Maven01——简介、安装配置、入门程序、项目构建和依赖管理

    1 Maven的简介 1.1 什么是maven 是apache下的一个开源项目,是纯java开发,并且只是用来管理java项目的 Svn eclipse   maven量级 1.2 Maven好处 同 ...

  7. 大型网站的 HTTPS 实践(一)—— HTTPS 协议和原理

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt387 1 前言 百度已经于近日上线了全站 HTTPS 的安全搜索,默认会将 ...

  8. Linux-mknod命令(9)

    mknod命令用于创建字符设备文件和块设备文件 (ls /dev -l 结果显示b开头和c开头的,即标识了块设备和字符设备.) 为了管理设备,所以设备中都有两个设备号:  主设备号:为了区分不同类型的 ...

  9. 为什么会需要消息队列(MQ)?

    为什么会需要消息队列(MQ)? #################################################################################### ...

  10. 201521123061 《Java程序设计》第六周学习总结

    201521123061 <Java程序设计>第六周学习总结 ***代码阅读:Child压缩包内 1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核 ...