「网络流24题」最长不下降子序列问题

Posted qixingzhi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「网络流24题」最长不下降子序列问题相关的知识,希望对你有一定的参考价值。

传送门:>Here<

题意:

给定正整数序列$x_1,...,x_n$

(1)计算其最长不下降子序列的长度s。

(2)计算从给定的序列中最多可取出多少个长度为s的不下降子序列。

(3)如果允许在取出的序列中多次使用$x_1$和$x_n$,则从给定序列中最多可取出多少个长度为$s$的不下降子序列。

思路分析

题意首先就很坑:注意第二问中的取出二字,意味着一个数字最多只能存在于一个LIS中。所以才会有第三问的假设

第一问很简单,直接暴力$O(n^2)$就好了

后面的两问需要借助于网络流。很容易想到:令S到T的任意一条路径表示一个LIS,并且设边的容量为1。这样的话最大流也就是能取出的LIS数量(和二分图匹配原理一样,一个点不会被用两次)

因此我们还是需要像二分图匹配一样拆点,每个点拆为两个。然后令$f[i]=1$的点连源点,$f[i]=maxs$的点连汇点。然后我们最初的想法是f值连续递增的并且能组成不下降子序列的两数之间连边即可。但这里情况也许不同了,想象一个类似$5,4,3,2,1$这样完全下降的序列,这样的话两部分的点之间不能连任何边,最大流跑出来是0。然而由于LIS长度为1,很明显有5种取法!

因此我们考虑,被拆的两个点自己连到自己,并且递增的边反过来连,就能解决问题。这样表达不清晰,下面详细阐述如何连边:

首先原序列做LIS,其中$f[i]$表示以$a[i]$为结尾的LIS的最大长度。对序列的每一个数进行拆点,也就是分为$X_i, Y_i$。我们要让S到T的每一条路径都是一个LIS,因此若$f[i]=1$,则$X_i$的点连接源点,$f[i]=maxs$则$Y_i$连接汇点。其中对于每一个数字,连接有向边$(X_i, Y_i)$。并且在做LIS的过程中,若发现一对数字满足$a[j]<=a[i] 且 f[j]+1=f[i]$,则连有向边$(Y_j, X_i)$。最后做最大流即可

Code

细节题

以上是关于「网络流24题」最长不下降子序列问题的主要内容,如果未能解决你的问题,请参考以下文章

「网络流24题」最长不下降子序列问题

洛谷2766:[网络流24题]最长不下降子序列问题——题解

P2766 [网络流24题]最长不下降子序列问题

最长不下降子序列问题 网络流24题

[网络流24题] 最长递增子序列

网络流24题(wll24)