假设我有一系列具有长度$ n $的整数。如何输出最长的减少序列? (一个子序列由不必遵守的阵列的要素组成,例如$(3,2,1)$是$(7,3,5,2,0,1)$的下降额度。我知道如何计算最长减少序列的长度,但不知道如何报告最长的减少序列。

伪代码将有所帮助。

有帮助吗?

解决方案

将以下序列视为您的输入:

$$ N,N-2,N-1,N-3,N-5,N-4,N-6,N-8,N-8,N-7,N-9,....,N-3 CDOT K -2,N -3 CDOT K -1,N -3 CDOT K -3,.... $$

为简单起见,假设$ n = 3 cdot t + 1 $,最长的子序列长度将为$ t $,长度$ t $ t $的缩小子序列的数量为$ 2^t $。

因此,可用解决方案的数量为$ theta(2^{n/3})$。但是,为什么这样,只需用DAG对其进行建模,请注意,如果$→$ b $,如果$ a> b $和$ b $和$ b $是$ a $ a $原始序列。

因此,由于输出大小可能是指数级的,因此您的最佳选择是创建DAG,并以DAG或任何其他列举所有可接受方式的方式找到所有最长的路径。

其他提示

- 递归辅助功能

    list form_longest_sublist_from(list array,list buffer,from) 
            add array[from] to buffer

            list ret as copy of buffer
            from i = from - 1 to -1 step -1
                   if last buffer > array[i] 
                   list sbuffer
                   sbuffer = form_longest_sublist_from(array,buffer,i);
                   if length sbuffer > length ret
                      ret = sbuffer;
                   endif
                endif
            endfor
            return ret;
    endfunc
  • 使用该功能的算法

    list of lists arrayoflongestlist
        list buffer;
        from i = length array - 1 to -1 step -1
            clear buffer
            add array[i] to buffer
            from x = i - 1 to -1 step -1
                if(array[x] < last buffer
                    list sbuffer;
                    sbuffer = form_longest_sublist_from(array,buffer,x);
                    if length sbuffer > length buffer)
                        buffer = sbuffer;
                                endif
                endif
            endfor
                if length arrayoflongestlist > 0
                       if length (last arrayoflongestlist) < length buffer
                                clear arrayoflongestlist
                                add buffer to arrayoflongestlist
                       endif
                       else if length (last arrayoflongestlist) == length buffer
                    add buffer to arrayoflongestlist
                endif
    
                       if length (last arrayoflongestlist) > i)
                    break;
            else
                add buffer to arrayoflongestlist
            endif
        endfor
    

我基本上将整个算法重新确定为适合该问题。

基本想法是从数组中的每个可能点(每个元素)启动,并通过将其余的数组的其余部分降低所有可能的订阅者,并查看哪些元素较小,并使用这些元素来启动递归从该点开始之前,然后过滤回到最长列表的递归之前。

考虑到该算法,我可能最糟糕的/最佳案例是原因是原因。

对于每个减少序列,将初始位置存储在另一个数组中。

for( i = 0; i < n-1; i++ ) {
    if ( a[i] > a[i+1] ) {
        temp[j++] = i;
        while( a[i] > a[i+1] ) {
            i++;
        }
        temp[j++] = i;
    }
}

现在,阵列温度将包含所有降低序列的初始和最终位置。然后打印它们

许可以下: CC-BY-SA归因
不隶属于 cs.stackexchange
scroll top