GESP 客观题评测系统

普及组 CSP-J 2026 初赛模拟卷 4

CSPJ-2026-R1-Mock-4

试卷解析总览,可直接查看每题答案与解析。

一、单项选择题

(共 15 题,每题 2 分,共计 30 分;每题有且仅有一个正确选项)

1 题(单选题2 分)

在 NOI Linux 的终端中,要列出当前目录下所有文件和文件夹的详细信息(包括权限、大小、修改时间等),应该使用命令( )。

A.
`ls`
B.
`ls -l`
C.
`ls -a`
D.
`ls -s`

正确答案B

解析详情

【答案】B

【考点】Linux 文件命令

【解析】 `ls -l` 使用长格式列出名称、权限、链接数、所有者、大小和修改时间等详细信息。

【易错点】 `ls -a` 负责显示隐藏文件,但本身不提供长格式详情。

2 题(单选题2 分)

在计算机网络中,IP 地址 192.168.1.1 属于( )地址。

A.
A 类
B.
B 类
C.
C 类
D.
D 类

正确答案C

解析详情

【答案】C

【考点】IPv4 分类地址

【解析】 分类地址按首字节判断:C 类地址范围为 192~223,因此 192.168.1.1 属于 C 类。

【易错点】 不要把 192.168.0.0/16 的私有地址属性与 A、B、C 类分类混淆。

3 题(单选题2 分)

在 C++ 中,表达式 `!(5 > 3) && (4 <= 4) || (2 != 2)` 的结果是( )。

A.
`true`
B.
`false`
C.
`1`
D.
编译错误

正确答案B

解析详情

【答案】B

【考点】逻辑运算

【解析】 `5 > 3` 为真,取反后为假;假与任何值进行 `&&` 仍为假,`2 != 2` 也为假,所以整个表达式为 `false`。

【易错点】 逻辑运算结果虽可转换为整数 0/1,但表达式的布尔结果是 `false`。

4 题(单选题2 分)

关于单向链表,以下描述中正确的是( )。

A.
可以随机访问任意位置的元素
B.
插入和删除元素的时间复杂度都是 O(1)O(1)
C.
需要连续的存储空间
D.
每个节点包含数据和指向下一个节点的指针

正确答案D

解析详情

【答案】D

【考点】单向链表

【解析】 单向链表的每个节点保存数据以及指向下一个节点的指针,节点不要求连续存储。

【易错点】 只有已知插入或删除位置时操作才可为 O(1)O(1),查找位置仍可能需要 O(n)O(n)

5 题(单选题2 分)

对于有 nn 个节点的二叉树,其最小高度是( )。

A.
log2n\lceil\log_2 n\rceil
B.
log2(n+1)1\lceil\log_2(n+1)\rceil-1
C.
n1n-1
D.
1

正确答案B

解析详情

【答案】B

【考点】二叉树高度

【解析】 高度按边数计算时,高度为 hh 的二叉树最多有 2h+112^{h+1}-1 个节点;反解得最小高度为 lceillog2(n+1)ceil1lceillog_2(n+1) ceil-1

【易错点】 要先确认高度从 0 开始计算,不能直接套层数公式。

6 题(单选题2 分)

将十进制小数 100.25 转换为二进制数,结果是( )。

A.
1010100.01
B.
1100100.11
C.
1100100.01
D.
1010100.11

正确答案C

解析详情

【答案】C

【考点】进制转换

【解析】 整数部分 100=64+32+4100=64+32+4,二进制为 `1100100`;小数 0.25=220.25=2^{-2},二进制为 `.01`,合并得 `1100100.01`。

【易错点】 小数部分应按二进制负次幂换算。

7 题(单选题2 分)

(考试成绩排序)场景:老师需要对全班 50 名学生的成绩排序,要求相同分数的学生保持原来的相对顺序。下列排序算法中最合适的是( )。

A.
快速排序
B.
堆排序
C.
归并排序
D.
选择排序

正确答案C

解析详情

【答案】C

【考点】稳定排序

【解析】 归并排序在相等元素时优先取左半部分即可保持原相对顺序,是四个选项中的稳定排序。

【易错点】 快速排序、堆排序和选择排序的常见实现都不稳定。

8 题(单选题2 分)

突然断电后,数据不会丢失的存储设备是( )。

A.
内存
B.
缓存
C.
固态硬盘
D.
寄存器

正确答案C

解析详情

【答案】C

【考点】存储器易失性

【解析】 固态硬盘使用非易失性闪存,断电后仍能保存数据;内存、缓存和寄存器均为易失性存储。

【易错点】 速度快不代表断电后能够保留数据。

9 题(单选题2 分)

使用深度优先搜索(DFS)遍历一个 nnmm 列的矩阵。从左上角开始搜索,每次只能向右或向下移动一个位置。在搜索过程中,需要使用一个栈来维护当前搜索路径上的已访问位置。为了确保能够完成整个矩阵的遍历,栈的大小至少为( )。(注:本题不考虑栈空间的大小限制。)

A.
max(n,m)\max(n,m)
B.
m+nm+n
C.
m+n1m+n-1
D.
n×mn\times m

正确答案C

解析详情

【答案】C

【考点】深度优先搜索栈

【解析】 只向右或向下移动时,从左上角到右下角的最长路径包含 n+m1n+m-1 个位置,因此路径栈至少要能容纳这么多元素。

【易错点】 计算节点数时不能只算移动次数 n+m2n+m-2

10 题(单选题2 分)

以下代码的时间复杂度是( )。

int n, i = 1;
cin >> n;
while (i < n) {
    i = i * 3;
}
A.
O(1)O(1)
B.
O(n)O(n)
C.
O(logn)O(\log n)
D.
O(nlogn)O(n\log n)

正确答案C

解析详情

【答案】C

【考点】循环复杂度

【解析】 变量 `i` 每轮乘 3,执行约 log3nlog_3 n 次;换底只带来常数因子,所以复杂度为 O(logn)O(log n)

【易错点】 循环变量指数增长时,循环次数不是 O(n)O(n)

11 题(单选题2 分)

某城市有 8 个交通枢纽,如果要建设一个完全图式的道路网络,使得任意两个枢纽之间都有直达道路,需要建设( )条道路。

A.
28
B.
64
C.
16
D.
7

正确答案A

解析详情

【答案】A

【考点】完全图

【解析】 8 个顶点的无向完全图边数为 inom{8}{2}=8 imes7/2=28

【易错点】 每条无向边连接一对顶点,不能把两个方向重复计数。

12 题(单选题2 分)

从 5 个不同的红球和 3 个不同的蓝球中,至少取 1 个球,最多取 4 个球,且红球和蓝球都必须至少取一个,不同的取法有( )种。

A.
120
B.
125
C.
180
D.
210

正确答案B

解析详情

【答案】B

【考点】组合计数

【解析】 取 2、3、4 个球且两色非空的方案数分别为 15、45、65,总数为 15+45+65=12515+45+65=125

【易错点】 既要排除只取一种颜色,也要注意所有球互不相同。

13 题(单选题2 分)

二叉树的节点按照先从上往下,后从左往右的顺序(对比“先行后列”的表达方式)进行编号,( )遍历方式可以按升序输出二叉搜索树的所有节点。

A.
前序
B.
中序
C.
后序
D.
层次

正确答案B(另接受:D)

解析详情

【答案】B

【考点】二叉搜索树遍历

【解析】 二叉搜索树满足左子树键值小于根、右子树键值大于根,因此中序遍历会按升序输出所有节点。

【易错点】 原答案表把前半句的层次编号误当成问题答案;系统同时兼容该原表选项。

14 题(单选题2 分)

一个时间复杂度为 O(n3)O(n^3) 的算法,当 nn 从 100 增大到 200 时,运行时间大约变为原来的( )倍。

A.
2
B.
4
C.
8
D.
16

正确答案C

解析详情

【答案】C

【考点】渐进复杂度

【解析】 当输入规模变为 2 倍时,立方复杂度的运行量变为 (2n)3/n3=8(2n)^3/n^3=8 倍。

【易错点】 不能只按输入规模的倍数线性估计运行时间。

15 题(单选题2 分)

一段时长 10 分钟的视频,分辨率为 1080P(1920×10801920\times1080),帧率为 30 帧/秒,颜色深度为 24 位。如果压缩比为 50:1,则压缩后的文件大小约为( )。

A.
1.2GB
B.
2.1GB
C.
2.24GB
D.
104.3GB

正确答案B

解析详情

【答案】B

【考点】视频容量

【解析】 原始容量约为 1920imes1080imes3imes30imes600approx104.31920 imes1080 imes3 imes30 imes600approx104.3GB,按 50:1 压缩后约为 2.09GB,最接近 2.1GB。

【易错点】 24 位颜色深度要先换成每像素 3 字节,并计入 10 分钟的总帧数。

二、阅读程序(1)

1 | #include <iostream>
2 | using namespace std;
3 | int solve(int x, int y) {
4 |     if (y == 0) return x;
5 |     if (x < y) swap(x, y);
6 |     return solve(y, x - y);
7 | }
8 | int main() {
9 |     int a, b;
10 |     cin >> a >> b;
11 |     int k = solve(a, b);
12 |     cout << a / k << "/" << b / k << endl;
13 |     return 0;
14 | }
15 | // 输入的 a 和 b 是不大于 10000 的正整数

16 题(判断题2 分)

函数 `solve(int x, int y)` 计算 xxyy 的最大公约数。( )

正确答案正确

解析详情

【答案】正确

【考点】最大公约数

【解析】 函数通过反复交换并相减,把问题化为更小的一对正整数;当第二个参数为 0 时,第一个参数就是最大公约数。

【易错点】 这是辗转相减法,不是求最小公倍数。

17 题(判断题2 分)

把第 5 行代码去掉,程序会正常输出,但结果数值可能不对。( )

正确答案错误

解析详情

【答案】错误

【考点】递归终止

【解析】 删除交换后,若 `x < y`,下一次会传入负数 `x-y`,递归不能按预期收敛,最终可能栈溢出而无法正常输出。

【易错点】 结果错误和程序无法正常结束是不同结论。

18 题(判断题2 分)

如果输入的值为 160 和 115,则程序的输出结果为 `23/32`。( )

正确答案错误

解析详情

【答案】错误

【考点】分数约分

【解析】 gcd(160,115)=5gcd(160,115)=5,程序输出 `160/5` 与 `115/5`,即 `32/23`,不是 `23/32`。

【易错点】 分子分母的输出顺序与输入顺序一致。

19 题(单选题4 分)

如果输入 1817 和 299,则输出为( )。

A.
1817/299
B.
97/13
C.
79/23
D.
79/13

正确答案D

解析详情

【答案】D

【考点】最大公约数应用

【解析】 gcd(1817,299)=23gcd(1817,299)=23,约分得到 1817/23=791817/23=79299/23=13299/23=13,所以输出 `79/13`。

【易错点】 必须同时用最大公约数约分分子和分母。

20 题(单选题4 分)

如果输入 x,yx,y1100001\ldots10000 中随机生成的数,则程序的平均时间复杂度为( )。

A.
O(1)O(1)
B.
O(logn)O(\log n)
C.
O(n)O(n)
D.
O(n2)O(n^2)

正确答案B

解析详情

【答案】B

【考点】平均时间复杂度

【解析】 对固定较大参数,辗转相减的平均步数与调和级数同阶;再对随机输入平均后仍为 O(logn)O(log n)

【易错点】 最坏情况下可达线性,题目问的是随机输入的平均复杂度。

二、阅读程序(2)

1 | #include <iostream>
2 | using namespace std;
3 | int main() {
4 |     int n, sum = 0;
5 |     cin >> n;
6 |     int arr[100];
7 |     for (int i = 0; i < n; i++) {
8 |         cin >> arr[i];
9 |     }
10 |     for (int i = 0; i < n; i++) {
11 |         int cnt = 0;
12 |         for (int j = 0; j < n; j++) {
13 |             if (arr[j] > arr[i]) {
14 |                 cnt++;
15 |             }
16 |         }
17 |         sum += (cnt == 1) * arr[i];
18 |     }
19 |     cout << sum << endl;
20 |     return 0;
21 | }
22 | // 输入的所有数为绝对值均不大于 1000 的整数

21 题(判断题2 分)

若输入数组为 `[5, 3, 8, 2]`,则程序输出为 5。( )

正确答案正确

解析详情

【答案】正确

【考点】程序执行模拟

【解析】 数组中只有 5 恰好有一个比它大的元素 8,因此累加值为 5。

【易错点】 条件统计的是比当前元素大的元素个数,不是当前元素的下标。

22 题(判断题2 分)

数组中可能存在多个元素满足条件,程序会将它们全部累加。( )

正确答案正确

解析详情

【答案】正确

【考点】重复元素与累加

【解析】 循环逐个检查数组位置;若多个元素各自满足 `cnt == 1`,语句会把它们分别加入 `sum`。

【易错点】 程序没有去重,相同数值位于不同位置时仍会分别处理。

23 题(判断题2 分)

如果程序输出为 0,则数组中的所有元素一定都相等。( )

正确答案错误

解析详情

【答案】错误

【考点】反例构造

【解析】 输出 0 还可能因为严格次大值本身为 0,或最大值重复导致没有元素满足 `cnt == 1`,并不能推出所有元素相等。

【易错点】 判断充分必要条件时,应检查能产生相同输出的其他输入。

24 题(单选题4 分)

若输入数组为 `[9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2]`,则输出为( )。

A.
-2
B.
-1
C.
8
D.
9

正确答案C

解析详情

【答案】C

【考点】程序执行模拟

【解析】 给定数组严格递减且元素互异,8 恰好只有一个更大的元素 9,因此程序输出 8。

【易错点】 最大元素的 `cnt` 为 0,不会被累加。

25 题(单选题3 分)

该程序计算的是数组中( )。

A.
第二大元素的值
B.
所有比平均值大的元素之和
C.
所有满足“恰好有一个元素比它大”的元素之和
D.
最大元素和最小元素的和

正确答案C

解析详情

【答案】C

【考点】嵌套循环含义

【解析】 对每个 `arr[i]`,内层循环统计严格大于它的元素数;程序累加所有统计值恰好为 1 的元素,所以选 C。

【易错点】 它不一定等价于一个单独的“第二大值”,重复元素会影响统计。

二、阅读程序(3)

1 | #include <iostream>
2 | #include <vector>
3 | #include <algorithm>
4 | using namespace std;
5 |
6 | int n, k, ans = 0;
7 | vector<int> nums;
8 | vector<bool> used;
9 |
10 | void dfs(int pos, int sum, int count) {
11 |     if (count == k) {
12 |         if (sum % 2 == 0) {
13 |             ans++;
14 |         }
15 |         return;
16 |     }
17 |     if (pos >= n) return;
18 |
19 |     if (!used[pos]) {
20 |         used[pos] = true;
21 |         dfs(pos + 1, sum + nums[pos], count + 1);
22 |         used[pos] = false;
23 |     }
24 |
25 |     dfs(pos + 1, sum, count);
26 | }
27 |
28 | int main() {
29 |     cin >> n >> k;
30 |     nums.resize(n);
31 |     used.resize(n, false);
32 |
33 |     for (int i = 0; i < n; i++) {
34 |         cin >> nums[i];
35 |     }
36 |
37 |     dfs(0, 0, 0);
38 |     cout << ans << endl;
39 |     return 0;
40 | }

26 题(判断题2 分)

如果输入数据中存在重复数字,则重复数字的数量不会影响输出结果。( )

正确答案错误

解析详情

【答案】错误

【考点】组合计数

【解析】 程序按数组位置选择元素,数值相同的位置仍代表不同选择,因此重复数字的数量会改变方案数。

【易错点】 不要把按位置选取误当成按不同数值选取。

27 题(判断题2 分)

去掉 `nums.resize(n);` 和 `used.resize(n, false);` 这两行代码,不会影响程序的正常运行。( )

正确答案错误

解析详情

【答案】错误

【考点】vector 容量

【解析】 代码通过下标写入 `nums[i]` 和访问 `used[pos]`;删除两次 `resize` 后两个 vector 为空,会发生越界访问。

【易错点】 `reserve` 或声明 vector 并不会自动创建可用的下标元素。

28 题(判断题2 分)

如果 n=10,k=2n=10,k=2nn 个数为 1~10 的任意排列,则输出结果是 2C522C_5^2。( )

正确答案正确

解析详情

【答案】正确

【考点】奇偶组合

【解析】 1~10 含 5 个奇数和 5 个偶数;两数之和为偶数需同奇偶,方案数为 inom{5}{2}+inom{5}{2}=2inom{5}{2}

【易错点】 奇偶各选一个得到的是奇数和。

29 题(单选题3 分)

如果输入的 kk 为 0,则程序的输出结果为( )。

A.
0
B.
1
C.
需要结合数组的数值,才能计算结果
D.
以上都不对

正确答案B

解析详情

【答案】B

【考点】递归边界

【解析】 当 k=0k=0 时首次调用已满足 `count == k`,且初始和 0 为偶数,因此 `ans` 加 1 后返回,输出 1。

【易错点】 选择 0 个元素的空集是一种合法选择。

30 题(单选题4 分)

程序的时间复杂度是( )。

A.
O(n)O(n)
B.
O(n2)O(n^2)
C.
O(2n)O(2^n)
D.
O(nk)O(n^k)

正确答案C

解析详情

【答案】C

【考点】回溯复杂度

【解析】 每个元素都有选或不选两个分支;在最坏情况下会遍历指数数量的状态,所以时间复杂度为 O(2n)O(2^n)

【易错点】 固定很小的 kk 可减少状态,但题目没有给出这样的限制。

三、完善程序(1)归并排序

归并排序算法通过递归地将数组不断地分割为更小的子数组,然后将这些子数组合并成有序数组,最终完成整个数组的排序。该排序为稳定排序,且时间复杂度较低。

1 | #include <iostream>
2 | #define N 100009
3 | using namespace std;
4 | int n;
5 | int a[N], L[N], R[N];
6 |
7 | void merge(int l, int m, int r) {
8 |     int n1 = m - l + 1;
9 |     int n2 = r - m;
10 |
11 |     for (int i = 0; i < n1; i++)
12 |         L[i] = a[l + i];
13 |     for (int j = 0; j < n2; j++)
14 |         R[j] = a[];
15 |
16 |     int i = 0, j = 0, k = l;
17 |     while () {
18 |         if (L[i] <= R[j]) {
19 |             a[k] = L[i++];
20 |         } else {
21 |             a[k] = R[j++];
22 |         }
23 |         ++k;
24 |     }
25 |     while (i < n1) {
26 |         a[k++] = L[i++];
27 |     }
28 |     while (j < n2) {
29 |         a[k++] = R[j++];
30 |     }
31 | }
32 |
33 | void mSort(int left, int right) {
34 |     if (left < right) {
35 |         int mid = left + (right - left) / 2;
36 |         mSort(left, mid);
37 |         mSort(mid + 1, right);
38 |         merge();
39 |     }
40 | }
41 |
42 | int main() {
43 |     cin >> n;
44 |     for (int i = 0; i < n; i++) {
45 |         cin >> a[i];
46 |     }
47 |     mSort();
48 |     for (int i = 0; i < n - 1; i++) {
49 |         cout << a[i] << " ";
50 |     }
51 |     cout <<  << endl;
52 |     return 0;
53 | }
54 |
55 |
56 |

31 题(单选题3 分)

① 处应填( )。

A.
j
B.
j + 1
C.
m + j
D.
m + 1 + j

正确答案D

解析详情

【答案】D

【考点】归并排序右半段

【解析】 右子数组从原数组下标 m+1m+1 开始,第 jj 个元素应取 `a[m + 1 + j]`。

【易错点】 `j` 是临时数组下标,不能直接作为原数组下标。

32 题(单选题3 分)

② 处应填( )。

A.
i < n && j < n
B.
i <= n && j <= n
C.
i < n1 && j < n2
D.
i <= n1 && j <= n2

正确答案C

解析详情

【答案】C

【考点】归并边界

【解析】 合并时只有 `i < n1 && j < n2` 才能同时安全读取 `L[i]` 和 `R[j]`。

【易错点】 数组下标到长度减 1 为止,不能使用 `<=`。

33 题(单选题3 分)

③ 处应填( )。

A.
mid, left, right
B.
right, left, mid
C.
left, mid, right
D.
left, right, mid

正确答案C

解析详情

【答案】C

【考点】归并函数参数

【解析】 当前待合并区间为 `[left,right]`,分界点是 `mid`,与 `merge(l,m,r)` 对应,应传 `left, mid, right`。

【易错点】 参数顺序由函数签名决定。

34 题(单选题3 分)

④ 处应填( )。

A.
0, n - 1
B.
0, n
C.
1, n - 1
D.
1, n

正确答案A

解析详情

【答案】A

【考点】归并排序区间

【解析】 数组有效下标是 0 到 n1n-1,首次排序应调用 `mSort(0, n - 1)`。

【易错点】 把右端点写成 n 会访问数组范围外的位置。

35 题(单选题3 分)

⑤ 处应填( )。

A.
" " << a[n - 1]
B.
a[n - 1]
C.
" " << a[n]
D.
a[n]

正确答案B

解析详情

【答案】B

【考点】格式化输出

【解析】 循环已输出前 n1n-1 个元素及其后的空格,最后只需输出 `a[n - 1]`,即可避免行末多余空格。

【易错点】 `a[n]` 越界,而再输出前导空格会产生两个连续空格。

三、完善程序(2)最长波动子序列

波动序列指序列中的元素值交替上升和下降,最长波动子序列是已有的序列中满足这种波动性质的最长子序列。

1 | #include <iostream>
2 | #include <vector>
3 | #include <algorithm>
4 | #define N 1009
5 | using namespace std;
6 | int n;
7 | int dp[N][2];
8 | int main() {
9 |     cin >> n;
10 |     vector<int> nums(n);
11 |     for (int i = 0; i < n; i++) {
12 |         cin >> nums[i];
13 |     }
14 |
15 |     
16 |     for (int i = 1; i < n; i++) {
17 |         for (int j = 0; ; j++) {
18 |             if () {
19 |                 int tmp = dp[j][1] + 1;
20 |                 if (tmp > dp[i][0]) {
21 |                     dp[i][0] = tmp;
22 |                 }
23 |             }
24 |             else if (nums[i] < nums[j]) {
25 |                 int tmp = ;
26 |                 if (tmp > dp[i][1]) {
27 |                     dp[i][1] = tmp;
28 |                 }
29 |             }
30 |         }
31 |     }
32 |
33 |
34 |     int max_Len = 1;
35 |     for (int i = 1; i < n; i++) {
36 |         max_Len = max(max_Len, );
37 |     }
38 |
39 |     cout << max_Len << endl;
40 |
41 |     return 0;
42 | }

36 题(单选题3 分)

① 处应填( )。

A.
memset(dp, 1, sizeof(dp));
B.
memset(dp, 0x3f, sizeof(dp));
C.
fill(dp, dp + n * 2, 1);
D.
fill(dp[0], dp[0] + n * 2, 1);

正确答案D

解析详情

【答案】D

【考点】二维数组初始化

【解析】 `dp` 的 2n2n 个连续整数都应初始化为 1,`fill(dp[0], dp[0] + n * 2, 1)` 能完成该操作。

【易错点】 `memset(...,1,...)` 会把每个字节写成 1,整数值并不是 1。

37 题(单选题3 分)

② 处应填( )。

A.
j < n
B.
j <= n
C.
j < i
D.
j <= i

正确答案C

解析详情

【答案】C

【考点】动态规划枚举

【解析】 计算第 ii 个位置的状态时,只能从它之前的下标转移,因此应枚举 `j < i`。

【易错点】 若允许 `j == i`,会用当前尚未完成的状态自我转移。

38 题(单选题3 分)

③ 处应填( )。

A.
nums[i] > nums[j]
B.
nums[i] >= nums[j]
C.
nums[j] > nums[i]
D.
nums[j] >= nums[i]

正确答案A

解析详情

【答案】A

【考点】波动子序列状态

【解析】 后续更新 `dp[i][0]` 使用的是以下降结束的 `dp[j][1]`,因此当前一步必须上升,即 `nums[i] > nums[j]`。

【易错点】 相等元素不能形成上升或下降。

39 题(单选题3 分)

④ 处应填( )。

A.
dp[i][0] + 1
B.
dp[i][1] + 1
C.
dp[j][0] + 1
D.
dp[j][1] + 1

正确答案C

解析详情

【答案】C

【考点】动态规划转移

【解析】 当 `nums[i] < nums[j]` 时形成一次下降,应由以前一个位置上升结束的状态转移,故为 `dp[j][0] + 1`。

【易错点】 新状态属于 i,转移来源仍应是 j 的相反方向状态。

40 题(单选题3 分)

⑤ 处应填( )。

A.
dp[i][0]
B.
dp[i][1]
C.
max(dp[i][0], dp[i][1])
D.
min(dp[i][0], dp[i][1])

正确答案C

解析详情

【答案】C

【考点】最长波动子序列

【解析】 以位置 ii 结尾的最优长度可能最后上升,也可能最后下降,应取 `max(dp[i][0], dp[i][1])`。

【易错点】 只检查其中一个方向会漏掉另一类最优序列。