Python 求最长子序列的长度

Python 求最长子序列的长度,python,algorithm,data-structures,substring,sequence,Python,Algorithm,Data Structures,Substring,Sequence,在这里,在这段代码中,它打印一个序列的最大子序列的长度,该序列先增大后减小,反之亦然 例如: 输入:1,11,2,10,4,5,2,1 输出:6(长度为6的最长子序列为1、2、10、4、2、1) 但是我怎样才能使它在三个单调(递增或递减)区域中工作呢 像增加减少增加或减少 例如: 输入:71616207181825125121112952111332619 产出:12 (最大子序列:71617182525111533)正如我们所看到的 它可以分为三个区域: 7,1/6,17,18,25,25/2

在这里,在这段代码中,它打印一个序列的最大子序列的长度,该序列先增大后减小,反之亦然

例如:

输入:1,11,2,10,4,5,2,1

输出:6(长度为6的最长子序列为1、2、10、4、2、1)

但是我怎样才能使它在三个单调(递增或递减)区域中工作呢

像增加减少增加或减少

例如:

输入:71616207181825125121112952111332619

产出:12

(最大子序列:71617182525111533)正如我们所看到的

它可以分为三个区域: 7,1/6,17,18,25,25/21,11,5,3,3

arr = list(map(int, input().split()))
def lbs(arr): 
    n = len(arr) 

    lis = [1 for i in range(n+1)] 

    for i in range(1 , n): 
        for j in range(0 , i): 
            if ((arr[i] > arr[j]) and (lis[i] < lis[j] +1)): 
                lis[i] = lis[j] + 1


    lds = [1 for i in range(n+1)] 

    for i in reversed(range(n-1)):
        for j in reversed(range(i-1 ,n)):  
            if(arr[i] > arr[j] and lds[i] < lds[j] + 1): 
                lds[i] = lds[j] + 1 



    maximum = lis[0] + lds[0] - 1
    for i in range(1 , n): 
        maximum = max((lis[i] + lds[i]-1), maximum) 

    return maximum 

print ("Length of LBS is",lbs(arr)) 
arr=list(映射(int,input().split())
def磅(arr):
n=长度(arr)
lis=[1代表范围内的i(n+1)]
对于范围(1,n)内的i:
对于范围(0,i)内的j:
如果((arr[i]>arr[j])和(lis[i]arr[j]和lds[i]
我想出了一个O(n^2 logn)的主意

您希望将整个段分成三部分:第一部分包含递增子序列,第二部分包含递减子序列,最后一部分包含再次递增子序列

首先,让我们选择一个序列的前缀-第一部分(O(n)可能性)。为了最小化检查间隔的数量,您只能选择前缀,即最后一个元素位于其最长的递增子序列中。(换句话说,当选择范围[1,x]时,a_x应位于其最长的递增子序列中)


现在您遇到了与您已经解决的问题类似的问题—查找递减,然后增加子序列(顺便说一句,我将使用二进制搜索而不是您使用的for循环)。唯一的区别是递减子序列必须从小于所选前缀最后一个元素的值开始(忽略任何较大或相等的值)-您可以在O(n log n)中执行此操作。

我认为您的方法与您所做的声明不一致。你说你在寻找一个子序列,这通常意味着一个整数子序列。您正在跳过值。在你的第二部分进一步提到了“单调递增/递减区域”,你又一次跳过了值,这使得这个问题非常复杂。例如,按照您跳过值的方法,第一次输入的答案可能是[1,11],[10,5,2,1]。@Jeff H,我并不同意您的看法。子序列通常用于不一定连续的段(例如:LCS、LIS问题等)。然而,“地区”这个词可能确实很麻烦。