Codechef:最长的奇怪子序列

时间:2012-03-18 11:55:36

标签: dynamic-programming

问题可以在http://www.codechef.com/MARCH12/problems/LWS/

找到

使用动态编程可以解决此问题。这个问题的诀窍是想出一个好的dp状态。我们可以利用输入字符串S [1..n]中唯一允许的字符是小写的拉丁字母,即' a' - ' z'。因此,可以出现的不同字符数不能超过26个。

因此我们提出了以下dp状态: dp [k] [c1] [c2] =子串S [1..k]的LWS的长度,使得非递减子序列以c1结束,而非递增子序列以c2结束。 一旦我们确定了州,我们就可以轻松地提出以下重复: 为了计算dp [k] [c1] [c2],我们尝试将小写字母S [k]添加到非递增子序列或非递减子序列中,或者我们不将它们添加到它们中的任何一个。

因此,如果c1 <= S [k]:dp [k] [S [k]] [c2] = max(dp [k] [S [k]] [c2],则dp [k-1] [c1] [c2] +1)并且类似地,如果c2> = S [k] dp [k] [c1] [S [k]] = max(dp [k] [c1] [S [k]],dp [k-1] [c1] [c2] +1)通过迭代c1和c2并找出所有dp [n] [c1] [c2]中的最大值,可以找到最终答案。 我们可以看到,对于从1到n的子串的每个可能长度,我们必须计算26 * 26个状态,其中n是字符串的长度。因此,解的顺序是O(26 * 26 * n)。

然而,当我们需要解决它时,如果列表中的元素是0到10 ^ 6之间的数字

1 个答案:

答案 0 :(得分:1)

时间和空间之间会有权衡。当序列的元素是0到10 ^ 6之间的数字时,问题中给出的解决方案将不起作用。

我们知道可以在O(nLgn)中找到最长的增加子序列。 让原始序列保存在数组A中 设有一个数组I,这样I [n]将保存最长增长子序列的长度直到A [n]。 假设有一个数组D,这样D [n]将从A [n]到A的末尾保存最长减少子序列的长度。 现在,你需要找到max(I [k] + D [k]) - 1。