我需要编写一个程序,在 -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;
}
答案 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
非空。)