我正在尝试找到主题算法而且卡住了。基本上,我采用了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