1. 预备知识

    DP(Dynamic Programming):一种以无后效性的状态转移为基础的算法,我们可以将其不严谨地先理解为递推。例如斐波那契数列的递推求法可以不严谨地认为是DP。当然DP的状态也可以是二维/三维的,某一维的含义也不仅仅是指某个数列的第几项。

    树状数组(BIT or fenwick tree):一种高效地动态维护一个序列并动态求取前缀和的数据结构。修改某个元素/求一次前缀和的时间复杂度均为O(logn)

  2 LIS

    好了现在假设你们都会打树状数组了(如果不会的话,baidu一发吧!顺便把线段树也自学了吧!如果学不会树状数组只把线段树自学了也成因为好像并没有树状数组能干而线段树干不了的事情),让我们做一道例题练习一下吧!。

    给出一个长度为n的序列,求LIS长度(LIS,longest increasing sequence,最长上升子序列,子序列定义为从原序列取出的一些未必相邻但保持原先的相对顺序的数,上升子序列满足子序列中前一个数严格小于后面的数)

    50% n<=5000,100% n<=50000

    50%的数据其实并没有用到树状数组。

    O(n^2)的LIS算法:定义f[i]为强制以第i项结尾时的LIS长度。那么从1到n依次求出每个f[i],f[i]可以由f[1...i-1]推出。

    好了,现在假设你们都会写50分了。我们考虑把算法优化到能跑50000

    首先离散化,将原先的数字对应到1-tot(tot为出现过的数值种类),例如10,10,20,15变成1,1,3,2

    那么我们定义g[i]为以数值i结尾的LIS长度,并从左向右扫描原数组,同时维护g数组。扫描1,1,3,2时,g数组变化如下:(未出现的项的值为0)

      a.g[1]=1

      b.g[1]=1

      c.g[1]=1,g[3]=2

      d.g[1]=1,g[2]=2,g[3]=2

    YY一下我们怎样用g数组完成DP。

    接下来我们需要一种数据结构支持单点修改(只增不减)和前缀最大值查询。

    首先来一个逗比分块写法维护g数组:将g均分成sz块,维护每一块的最大值。修改可以O(1)完成,前缀最大值查询可以将整块整块的部分用每一块的最大值求,零散部分暴力扫一遍。sz取在sqrt(n)附近的时候效率最高。总时间复杂度O(nsqrt(n)),自信AC。

    如果n<=233333?

    我们可以树状数组维护g数组。原始的树状数组改造后可以支持单点修改(只增不减)和前缀最大值查询。把树状数组的加法换成取最大值,YY一下。

    最后整个g数组的最大值就是答案。

  3. LCS

    好了,现在假设你们都会nlogn的LIS,让我们来一道例题练习一下吧!

    uva10635 Prince and Princess(数据范围是我口胡的)

    给出两个1~n的排列(一个1~n的排列中,1-n每个数字出现一次,不重复出现),求LCS(最长公共子序列)长度。50%的数据保证第一个排列为1,2,3,...n按顺序递增的。

    n<=233333

    50%数据是第二个排列的LIS。很好50分到手。

    下面设想一下,把数字重新编号,LCS长度不变。例如,两个序列为1,2,3; 3,2,1.那么a,b,c;c,b,a的答案是和它一样的。那么把数字编号为数字也是可以的。

    例如这两个数据:

    (1)

    4

    1 2 3 4

    2 3 4 1

    (2)

    4

    4 3 2 1

    3 2 1 4

    它们的答案是相同的。因为在求解LCS时,我们只关注两个序列某两个下标处的数值是否相同,重新编号没有改变“对应下标位置的数相同”的信息。

    那么我们把一个序列重编号为1,2,3...n,对另一个序列也用同样的对应关系重编号(即把第二个序列中每个数改成这个数在第一个序列中出现的下标),跑LIS,自信AC。

  4. more about LCS

    接下来我们分兵奇袭,用另一条思路得出刚才例题lcs的另一个nlogn做法。

    首先自己yy一下LCS的O(n^2)算法。它的状态定义为f[i][j]表示允许使用第一个序列的前i个元素,第二个序列的前j个元素(其中第i个,第j个元素不要求必须使用)

    接下来我们修改状态定义(这种事情在优化DP时需要经常干)使得它能优化到nlogn.

    新的状态中,f[i][j]表示允许使用第一个序列的前i个元素,第二个序列的前j个元素(其中第一个序列第i个元素不必须使用,第二个序列第j个元素必须使用

    于是我们把原先的DP改成分层的过程,考虑从f[i-1][]求出f[i][],那么这两个数组最多有一个位置不同(只有以第一个序列的第i个元素结尾的答案会发生改变)。

    那么我们动态维护这个数组就可以了。假如第一个序列中第i个元素在第二个序列中出现在第k个位置,那么修改f[k]即可(这里已经干掉了第一维)。

    f[k]等于什么?等于f[1...k-1]的最大值+1,因为在LCS中前一项一定是第二个序列前面k-1的项中的一项(如果已经是第一项,没有前一项?边界自己处理一下我就不(懒得)写了)。

    于是还是树状数组前缀最大值,只增不减的单点修改。

    事实上,这个算法只要保证匹配上的位置不多即可。因此1-n每个数字出现5次也是能写的。

    http://www.lydsy.com/JudgeOnline/problem.php?id=1264 bzoj1264基因匹配

  5。more about BIT&DP

    二维树状数组也是可以拿来优化DP的 http://www.lydsy.com/JudgeOnline/problem.php?id=3594  方伯伯的玉米田

    坐标系可以转...http://www.lydsy.com/JudgeOnline/problem.php?id=2131  免费馅饼

    和树状数组没关系的傻逼题 http://www.lydsy.com/JudgeOnline/problem.php?id=4300

    2016.12.31update:终于想到了一道noip题NOIP2012摆花 http://cogs.pro/cogs/problem/problem.php?pid=1270

  6. 巩固练习一下LIS

    http://www.lydsy.com/JudgeOnline/problem.php?id=3173

    http://www.lydsy.com/JudgeOnline/problem.php?id=4660

由于我太弱,所以这里的例题比较少...虚心求dalao们在评论区提供例题。

[noip科普]关于LIS和一类可以用树状数组优化的DP的更多相关文章

  1. 【转】关于LIS和一类可以用树状数组优化的DP 预备知识

    原文链接 http://www.cnblogs.com/liu-runda/p/6193690.html 预备知识 DP(Dynamic Programming):一种以无后效性的状态转移为基础的算法 ...

  2. NOIp 数据结构专题总结 (2):分块、树状数组、线段树

    系列索引: NOIp 数据结构专题总结 (1) NOIp 数据结构专题总结 (2) 分块 阅:<「分块」数列分块入门 1-9 by hzwer> 树状数组 Binary Indexed T ...

  3. HDU - 5542 The Battle of Chibi(LIS+树状数组优化)

    The Battle of Chibi Cao Cao made up a big army and was going to invade the whole South China. Yu Zho ...

  4. NOIP 2013 洛谷P1966 火柴排队 (树状数组求逆序对)

    对于a[],b[]两个数组,我们应选取其中一个为基准,再运用树状数组求逆序对的方法就行了. 大佬博客:https://www.cnblogs.com/luckyblock/p/11482130.htm ...

  5. nlogn求LIS(树状数组)

    之前一直是用二分 但是因为比较难理解,写的时候也容易忘记怎么写. 今天比赛讲评的时候讲了一种用树状数组求LIS的方法 (1)好理解,自然也好写(但代码量比二分的大) (2)扩展性强.这个解法顺带求出以 ...

  6. Codeforces 486E LIS of Sequence --树状数组求LIS

    题意: 一个序列可能有多个最长子序列,现在问每个元素是以下三个种类的哪一类: 1.不属于任何一个最长子序列 2.属于其中某些但不是全部最长子序列 3.属于全部最长子序列 解法: 我们先求出dp1[i] ...

  7. Codevs 3286 火柴排队 2013年NOIP全国联赛提高组 树状数组,逆序对

    题目:http://codevs.cn/problem/3286/ 3286 火柴排队  2013年NOIP全国联赛提高组  时间限制: 1 s   空间限制: 128000 KB   题目等级 : ...

  8. NOIP 2017 列队 - Splay - 树状数组

    题目传送门 传送点I 传送点II 题目大意 (家喻户晓的题目应该不需要大意) (我之前咋把NOIP 2017打成了NOIP 2018,好绝望) Solution 1 Splay 每行一颗Splay,没 ...

  9. Luogu 2680 NOIP 2015 运输计划(树链剖分,LCA,树状数组,树的重心,二分,差分)

    Luogu 2680 NOIP 2015 运输计划(树链剖分,LCA,树状数组,树的重心,二分,差分) Description L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之 ...

随机推荐

  1. asp.net获取服务端和客户端信息

    asp.net获取服务端和客户端信息 获取服务器名:Page.Server.ManchineName获取用户信息:Page.User 获取客户端电脑名:Page.Request.UserHostNam ...

  2. 从AdventureWorks学习数据库建模——保留历史数据

    在业务需求中,经常需要我们在系统中能够记录历史信息,能够查看到历史变动情况,这时我们可以通过增加开始结束时间字段来记录数据的历史版本.对数据的历史记录主要分为:关系.属性历史,实体历史和变更历史. 关 ...

  3. WPF 自定义进度条

    WPF设计界面过程中,有时需要设计一种可以手动滑动修改并实时显示的进度条 进度条,效果如下: 颜色.图标.节点什么的,都可以重新替换. 前端XAML代码: <UserControl x:Clas ...

  4. 再解java中的String

    今天看到一篇文章中,写了关于java中的String.我看了后,是我从学java来觉得是最好的一篇关于String类的文章.看了这篇文章你就会对String的认识会提高一个层次.故将原作者的文章特意转 ...

  5. diff/merge configuration in Team Foundation - common Command and Argument values - MSDN Blogs

    One of the extensibility points we have in Team Foundation V1 is that you can configure any other di ...

  6. 帆软报表FineReport数据库连接编码转换

    1. 问题描述 数据库会以某种编码方式保存与读取数据,FineReport解析时默认使用GBK字符集,若数据库端编码与设计器端编码不一致时,就会导致中文及特殊字符的乱码. FineReport在定义数 ...

  7. less简单入门

    官网地址 http://lesscss.org/ less手册 www.lesscss.net/ bootstrap官网less介绍 http://www.bootcss.com/p/lesscss/ ...

  8. tomcat配置SSL双向认证

    一.SSL简单介绍 SSL(Secure Sockets Layer 安全套接层)就是一种协议(规范),用于保障客户端和服务器端通信的安全,以免通信时传输的信息被窃取或者修改. 怎样保障数据传输安全? ...

  9. HDU 1524 A Chess Game【SG函数】

    题意:一个N个点的拓扑图,有M个棋子,两个人轮流操作,每次操作可以把一个点的棋子移动到它的一个后继点上(每个点可以放多个棋子),直到不能操作,问先手是否赢. 思路:DFS求每个点的SG值,没有后继的点 ...

  10. 基于移动端Reactive Native轮播组件的应用与开发详解

    总结下这段时间学习reactive native的一些东西,我们来认识一下,被炒得这么火的rn,究竟是个什么东西,以及如何去搭建自己的demo. reactive  native是什么 由facebo ...