排序子序列划分
问题描述
给定一个数组,判断其最少可以划分为多少个'排序子序列'。这里的排序子序列定义为连续的非递增或非递减子序列。
例如:1 2 3 2 2 1 可划分为 1 2 3(非递减)和 2 2 1(非递增),共 2 段。
思路分析
这道题的核心在于如何确定每一段的结束位置。
- 遍历策略:从数组头部开始,尝试扩展当前子序列。只要满足非递增或非递减条件,就继续向后延伸。
- 相等情况处理:遇到数值相同的区域时,这段相等序列既可以归入前一段,也可以作为新的一段开头。为了简化逻辑,我们通常将其视为过渡,直接跳过,直到发现明确的递增或递减趋势。
- 边界情况:
- 开头若为相等序列,无法立即判断方向,直接跳过即可,因为它能融入后续确定的序列中。
- 结尾若剩余元素无法与前一段合并,则单独计为一个子序列。
代码实现
#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]) { // 非递增趋势
(i < n && arr[i] >= arr[i + ]) i++;
ret++;
} {
(i < n && arr[i] == arr[i + ]) i++;
}
}
cout << ret << endl;
;
}


