具有最小总和的最长非递减子序列

时间:2017-09-01 20:52:16

标签: python algorithm sequence

我正在尝试找到主题算法而且卡住了。基本上,我采用了zzz's answer中给出的代码,这是最长增加子序列算法,以获得最长的非减少子序列。我的目标是找到具有最小总和(MSLNDS)并且不知道我有一个的LNDS。但据我所知,wikipedia上提供的原始LIS算法确实找到了 minimal sum LIS。其代码的文档字符串表示LIS算法保证如果存在多个递增子序列,则以最小值结尾的子序列是首选,如果该值的多次出现可以结束序列,则最早 < em>发生是首选。不知道最早发生的意思是什么,但是不愿意生成所有LNDS来找到我的MSLNDS。在我看来,templatetypedef给出的聪明的转换可以用来表明唯一的MSLIS转换为MSLNDS,但没有证据。所以,

a)维基百科上给出的LIS算法是否总是输出最小和LIS?

b)如果采用这种方式LIS算法,LNDS算法会保留这个属性吗?

def NDS(X):
    n = len(X)
    X = [0.0] + X
    M = [None]*(n+1)
    P = [None]*(n+1)
    L = 0
    for i in range(1,n+1):
        #########################################
        # for LIS algorithm, this line would be 
        # if L == 0 or X[M[1]] >= X[i]:
        #########################################
        if L == 0 or X[M[1]] > X[i]:
            j = 0
        else:
            lo = 1
            hi = L+1
            while lo < hi - 1:
                mid = (lo + hi)//2
                #########################################
                # for LIS algorithm, this line would be 
                # if X[M[mid]] < X[i]:
                #########################################
                if X[M[mid]] <= X[i]:
                    lo = mid
                else:
                    hi = mid
            j = lo

        P[i] = M[j]
        if j == L or X[i] < X[M[j+1]]:
            M[j+1] = i
            L = max(L,j+1)

    output = []
    pos = M[L]
    while L > 0:
        output.append(X[pos])
        pos = P[pos]
        L -= 1

    output.reverse()
    return output

0 个答案:

没有答案