📜  门| GATE-CS-2016(套装2)|第 59 题(1)

📅  最后修改于: 2023-12-03 15:12:43.525000             🧑  作者: Mango

GATE-CS-2016(套装2)|第 59 题

该题目要求给定一组数对,求出其中的最长递增子序列。即,找到一个序列,其中的元素组成一个递增的子序列,其长度最长。

本题可以通过动态规划的方法解决。

首先,定义状态。设 $L_i$ 表示以第 $i$ 个数为结尾的最长递增子序列的长度。

然后,考虑状态转移。设给定的数对为 $(a_1,b_1), (a_2,b_2), \dots, (a_n,b_n)$。对于 $1\leq i <j\leq n$,如果 $b_i < b_j$ 且 $L_i \geq L_j$,则有:

$$ L_j = L_i + 1 $$

最终答案即为所有 $L_i$ 中的最大值。

此外,通过记录每个 $L_i$ 对应的最长递增子序列,也可以从中得到一个最长递增子序列。具体来说,对于 $1\leq j\leq n$,如果 $L_j$ 最大,则以第 $j$ 个数为结尾的最长递增子序列即为前面若干个递增子序列的拼接再加上第 $j$ 个数。

下面是该算法的伪代码:

L = [1 for i in range(n)]
sequence = [[i] for i in range(n)]
for i in range(1, n):
    for j in range(i):
        if b[j] < b[i] and L[j] >= L[i]:
            L[i] = L[j] + 1
            sequence[i] = sequence[j] + [i]
return max(L), sequence[L.index(max(L))]

其中 n 是数对个数,b 是所有数对的第二个元素组成的列表。

代码片段:

L = [1 for i in range(n)]
sequence = [[i] for i in range(n)]
for i in range(1, n):
    for j in range(i):
        if b[j] < b[i] and L[j] >= L[i]:
            L[i] = L[j] + 1
            sequence[i] = sequence[j] + [i]
return max(L), sequence[L.index(max(L))]