用二分优化最长上升子序列,输出去除最长上升子序列的序列
时间: 2024-06-14 11:06:01 浏览: 147
最长上升子序列
要用二分优化最长上升子序列,可以使用动态规划的思想。首先,我们需要定义一个数组dp,其中dp[i]表示以第i个元素结尾的最长上升子序列的长度。然后,我们遍历原始序列,对于每个元素nums[i],我们在dp数组中找到一个位置j,使得nums[i]大于dp[j],但是小于dp[j+1],然后更新dp[j+1]为nums[i]。最后,我们找到dp数组中的最大值max_len,即为最长上升子序列的长度。
接下来,我们可以根据dp数组来构造最长上升子序列。我们从最后一个元素开始,如果dp[i]等于max_len,则将nums[i]加入到结果序列中,并将max_len减1,继续向前遍历。
下面是具体的代码实现:
```cpp
#include <iostream>
#include <vector>
using namespace std;
vector<int> getLongestIncreasingSubsequence(vector<int>& nums) {
int n = nums.size();
vector<int> dp(n, 1);
int max_len = 1;
int end_index = 0;
for (int i = 1; i < n; i++) {
for (int j = 0; j < i; j++) {
if (nums[i] > nums[j]) {
dp[i] = max(dp[i], dp[j] + 1);
}
}
if (dp[i] > max_len) {
max_len = dp[i];
end_index = i;
}
}
vector<int> result;
result.push_back(nums[end_index]);
max_len--;
for (int i = end_index - 1; i >= 0; i--) {
if (nums[i] < nums[end_index] && dp[i] == max_len) {
result.push_back(nums[i]);
max_len--;
}
}
reverse(result.begin(), result.end());
return result;
}
vector<int> removeLongestIncreasingSubsequence(vector<int>& nums) {
vector<int> longestSubsequence = getLongestIncreasingSubsequence(nums);
vector<int> result;
int i = 0, j = 0;
while (i < nums.size() && j < longestSubsequence.size()) {
if (nums[i] == longestSubsequence[j]) {
i++;
j++;
} else {
result.push_back(nums[i]);
i++;
}
}
while (i < nums.size()) {
result.push_back(nums[i]);
i++;
}
return result;
}
int main() {
vector<int> nums = {10, 9, 2, 5, 3, 7, 101, 18};
vector<int> result = removeLongestIncreasingSubsequence(nums);
cout << "去除最长上升子序列后的序列为:";
for (int i = 0; i < result.size(); i++) {
cout << result[i] << " ";
}
cout << endl;
return 0;
}
```
这段代码中,getLongestIncreasingSubsequence函数用于获取最长上升子序列,removeLongestIncreasingSubsequence函数用于去除最长上升子序列。在主函数中,我们可以自定义一个序列nums,并调用removeLongestIncreasingSubsequence函数来输出去除最长上升子序列的序列。
阅读全文