打印所有可能的最长减少子序列

时间:2012-04-15 11:47:22

标签: c++ algorithm

我有一个整数数组A [1 ... N]。现在我想要打印所有最长的减少后续数据。我已经完成了大部分教程,但是所有教程只打印了一个LDS。假设LDS的长度是5,那么大多数只打印一个长度为5的LDS。 但我想打印所有可能的LDS。如何做到这一点?可以在O(nlongn)时间内完成。伪代码将更有帮助。

2 个答案:

答案 0 :(得分:1)

您可以随时跟踪所有最长(到目前为止)的子序列:

// If you have only one element, that is the longest descending subsequence
// Otherwise store first element as previous

if: current element is less than (or equal to) previous
  // decreasing
  increase current subsequence length
  add element to current subsequence
else:
  // increasing
  set current subsequence length to 0
  empty current subsequence

if: current subsequence is longer than current maximum
  invalidate all current max subsequences
  set current maximum subsequence length to current subsequence length
  add current subsequence to set of longest subsequences
else if: current subsequence is same size as current maximum
  add current subsequence to set of longest subsequences

答案 1 :(得分:1)

如果您从教程中取消优化算法,并使用更简单的N^2算法进行线性搜索而不是在地图中查找,则更容易理解这个想法。然后修改打印序列的代码以向后搜索先前元素,而不是将其存储在vector<int> pre中。然后你可以用一个简单的递归回溯器打印所有序列:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

void print_all(
    const vector<int> seq
,   const vector<int>& len
,   int max, int pos
,   vector<int>& sofar) {
    if (max == 0) {
        for (int i = sofar.size()-1 ; i >= 0 ; i--)
            cout << sofar[i] << " ";
        cout << endl;
        return;
    }
    int val = pos < seq.size() ? seq[pos] : -1;
    for (int i = pos-1 ; i >= 0 ; i--) {
        if (len[i] == max && seq[i] > val) {
            sofar.push_back(seq[i]);
            print_all(seq, len, max-1, i, sofar);
            sofar.erase(sofar.end()-1);
        }
    }
}

int main() {
    int data[] = {5, 30, 2, 17, 92, 11, 7, 10, 2, 1};
    vector<int> seq(data, data+10);
    vector<int> len(seq.size());
    for (int i = 0 ; i < seq.size() ; i++) {
        len[i] = 1;
        for (int j = i-1 ; j >= 0 ; j--)
            if (seq[j] > seq[i] && len[j]+1 > len[i])
                len[i] = len[j]+1;
    }
    int max = *max_element(len.begin(), len.end());
    cerr << max << endl;
    vector<int> sofar;
    print_all(seq, len, max, seq.size(), sofar);
}