我已经做了一系列研究,找到M = 2序列的最长时间,但我试图弄清楚如何对M≥2序列进行研究
我被赋予N和M:M序列,具有N个独特元素。 N是{1 - N}的集合。我已经考虑过动态编程方法,但我仍然对如何实际合并它感到困惑。
示例输入
5 3
5 3 4 1 2
2 5 4 3 1
5 2 3 1 4
这里的最大序列可以看作是
5 3 1
预期输出
Length = 3
答案 0 :(得分:3)
一个简单的想法。
对于i
和1
之间的每个数字N
,计算最后一个数字为i
的最长子序列。 (我们称之为a[i]
)
为此,我们将从头到尾迭代第一个序列中的数字i
。如果a[i] > 1
,那么数字j
就会在每个序列中显示i
之前的数字。
现在我们可以检查j
的所有可能值和(如果先前条件成立)a[i] = max(a[i], a[j] + 1)
。
最后一点,因为j
在第一个序列中位于i
之前,这意味着已经计算了a[j]
。
for each i in first_sequence
// for the OP's example, 'i' would take values [5, 3, 4, 1, 2], in this order
a[i] = 1;
for each j in 1..N
if j is before i in each sequence
a[i] = max(a[i], a[j] + 1)
end
end
end
如果您事先计算位置矩阵,则为O(N^2*M)
。
答案 1 :(得分:2)
由于你有独特的元素,@ Nikita Rybak的答案就是这样,但是既然你提到了动态编程,那么当你有两个以上的序列时,你可以使用DP:
dp[i, j, k] = length of longest common subsequence considering the prefixes
a[1..i], b[1..j], c[1..k].
dp[i, j, k] = 1 + dp[i - 1, j - 1, k - 1] if a[i] = b[j] = c[k]
= max(dp[i - 1, j, k], dp[i, j - 1, k], dp[i, j, k - 1]) otherwise
要获得实际的子序列,请使用从dp[a.Length, b.Length, c.Length]
开始的递归函数,并基本上反转上述公式:如果三个元素相等,则回溯到dp[a.Length - 1, b.Length - 1, c.Length - 1]
并打印字符。如果没有,请根据上述值的最大值进行回溯。
答案 2 :(得分:1)
您可以查看“Design of a new Deterministic Algorithm for finding Common DNA Subsequence”论文。您可以使用此算法构建DAG(第8页,图5)。从DAG中,读取最大的常见不同子序列。然后使用M的值尝试动态编程方法,以确定每个序列需要构建多少DAG。基本上使用这些子序列作为键并将相应的序列号存储在找到的位置,然后尝试找到最大的子序列(可以超过1)。