最长的非递减单调子序列c ++

时间:2016-12-19 16:16:49

标签: c++ vector max sequence

我需要编写一个程序,在 -10 10 5 的数字序列中找到最长的非递减子序列,例如,如果我的输入是:

  

6 6 6 2 2 7

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

  

6 6 6 7

如果我输入的是:

  

100 6 6 6 2 2 7

我的中途工作代码会返回 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;
 }

1 个答案:

答案 0 :(得分:0)

这是一个难题,因为您没有强制执行邻接,只是订单。这意味着您不能简单地采用第一个元素并假设测试它将找到答案(正如您的代码当前正在做的那样。)

我们可以通过dynamic programming 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,您就可以找到最长的非减少单调子序列&#34;像这样:

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

请注意,这需要您的输入数组非空,相应地dynamicTable非空。)

Live Example