最长的非降低单调子序列C

Longest non-decreasing monotonic subsequence c++

本文关键字:单调      更新时间:2023-10-16

我需要编写一个程序,该程序以 -10 10 5 <<em> -10 的数字顺序找到最长的非降低子序列/sup> ,例如,如果我的输入是:

6 6 6 2 2 7

我的程序将返回 4 ,原因是:

6 6 6 7

如果我的输入是:

100 6 6 6 2 2 7

我的中途工作代码将返回A 4

但是,如果我的输入是:

100 110 120 6 6 6 2 2 7

我的程序返回 3 ,原因

100 110 120

,但它应该再次返回 4 。我真的无法跟踪它出错的地方:

int FindIndex(std::vector<int> &v, int k, int result, int key) {
    while (result-k > 1) {
        int mid = k + (result-k)/2;
        if (v[mid] >= key)
            result = mid;
        else
            k = mid;
    }
    return result;
}
int main() {
    int n=0;
    while(cin >> n) {
        vector<int> v;
        int cur;
        while (cin >> cur) {
            v.push_back(cur);
            if (cin.get() == 'n') {
                break;
            }
        }
        if (v.size() == 0)
            return 0;
        vector<int> holder(v.size(), 0);
        int length = 1; 
        holder[0] = v[0];
        for (size_t i = 1; i < v.size(); i++) {
            if (v[i] < holder[0])
                holder[0] = v[i];
            else if (v[i] >= holder[length-1])
                holder[length++] = v[i];
            else
                holder[FindIndex(holder, -1, length-1, v[i])] = v[i];
        }
        cout  << length << endl;
    }
    return 0;
 }

这是一个困难的问题,因为您不执行邻接,而是订单。这意味着您不能简单地采用第一个元素,并假设对其进行测试会找到答案(因为您的代码当前正在执行。)

我们可以通过动态编程中的 o(n log(n)) o(n log(n))解决此问题:我们将从末端开始,并计算每个数字的最长增加序列。例如,给定的输入集:vector<int> v我们可以在vector<int> dynamicTable(size(v))中存储最长增加的序列,然后我们可以按以下方式填充它:

for(int i = size(v) - 1; i >= 0; --i) {
    for(int j = i + 1; j < size(v); ++j) {
        if(v[i] <= v[j]){
            dynamicTable[i] = max(dynamicTable[j], dynamicTable[i]);
        }
    }
    ++dynamicTable[i];
}

一旦 dynamicTable被填充了,您可以找到像这样的"最长的非折扣单调子序列":

*max_element(cbegin(dynamicTable), cend(dynamicTable))

请注意,这预计您的输入阵列是非空的,并且相应地dynamicTable是非空的。)

实时示例