一、排序子序列划分
题目解析
给定一个数组,判断这个子序列可以划分成多少个排序子序列。这里的排序子序列指的是连续的非递增或非递减子序列。
例如:1 2 3 2 2 1 可以划分成 1 2 3 和 2 2 1 两个排序子序列。
解题思路
这道题的核心在于贪心策略。我们只需要从左到右遍历数组,尽可能延长当前找到的排序子序列。
关键点:
- 方向判定:遇到数值相等的区域时,这段相等序列既可以接在前面的非递增序列后,也可以接在非递减序列后。因此,遇到相等元素时,直接跳过继续向后看,直到发现大小变化再确定方向。
- 边界处理:如果数组开头就是相等序列,直接跳过即可;如果最后一个元素无法与前一个序列合并,则单独作为一个新的子序列。
代码实现
#include <iostream>
using namespace std;
const int N = 1e5 + 10;
int arr[N];
int n;
int main() {
cin >> n;
for (int i = 0; i < n; i++) cin >> arr[i];
int ret = 0;
for (int i = 0; i < n; i++) {
if (i == n - 1) { // 数组最后一个位置
ret++;
break;
}
if (arr[i] < arr[i + 1]) { // 非递减
while (i < n && arr[i] <= arr[i + 1]) i++;
ret++;
} else if (arr[i] > arr[i + 1]) { // 非递增
while (i < n && arr[i] >= arr[i + ]) i++;
ret++;
} {
(i < n && arr[i] == arr[i + ]) i++;
}
}
cout << ret << endl;
;
}


