跳转至

6.最长不下降子序列问题

题目

给定正整数序列x1,...,xn 。 (1)计算其最长不下降子序列的长度s。 (2)计算从给定的序列中最多可取出多少个长度为s的不下降子序列。 (3)如果允许在取出的序列中多次使用x1和xn,则从给定序列中最多可取出多少个长度为s的不下降子序列。 设计有效算法完成(1)(2)(3)提出的计算任务。

题解

第一问

可以直接用 O(n^2)DP 来做。 设 f[i] 表示以 i 位置为结尾的最长不下降子序列。 然后转移很简单。 第一问的答案为 max{f[i]},设为 K

第二问

使用网络流解决,使用一种分层图的思想进行状态转移。 将每一个点 u 分成左右的两个点 u1, u2,然后由 u1u2 连一条容量为 1的边,这是为了保证每一个点最多只能使用一次,对于所有满足 f[i] = 1 的位置 i, 由 S 点向 i1 连边,对于所有满足 f[i] = K 的位置 i,由 i2T 连一条容量为 1 的边,此时到了进行模拟转移的时候,对于一个位置 i,找到所有位置 j,满足 j < i 而且 a[j] <= a[i] 而且 f[i] = f[j] + 1 ,其实就是 dp 中状态转移的条件。 然后由 j2i1 连一条容量为 1 的边。 跑出来最大流就是答案。

第三问

由于 x_1, x_n 可以使用多次,那么将 S1_1之间的边容量改为 inf, 1_11_2 之间的边容量也改为 inf,如果 f[N]=K 的话,就将 N_1N_2之间的边容量改为 infN_2T 之间的边的容量改为 inf, 此时跑出的最大流为第三问答案。