正在载入在线练习界面,本页内容可直接阅读…

AK CSP › CSP-J 2025 第一轮真题 › 第 31 题

CSP-J 2025 第一轮 第 31 题:程序(三):输出结果满足的性质

阅读程序 · 动态规划 · 难度 很难 · 答案 D

题目

#include <algorithm>
#include <cstdio>
#include <cstring>
#define ll long long
int f[5007][5007];
int a[5007], b[5007];
int n;
int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
        scanf("%d", &a[i]);
    }
    for (int i = 1; i <= n; ++i) {
        scanf("%d", &b[i]);
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n; ++j) {
            f[i][j] = std::max(f[i][j], std::max(f[i - 1][j], f[i][j - 1]));
            if (a[i] == b[j]) {
                f[i][j] = std::max(f[i][j], f[i - 1][j - 1] + 1);
            }
        }
    }
    printf("%d\n", f[n][n]);
    return 0;
}
CSP-J 2025 第一轮 第 31 题 原题
原题扫描(页面加载后可直接在线作答)

本小题

输出的答案满足的性质有( )。

选项

  • A. 小于等于 $n$
  • B. 大于等于 $0$
  • C. 不一定大于等于 $1$
  • D. 以上均是

答案

D

题解

答案选 D.以上均是。

这段程序求的是数组 a 和 b 的最长公共子序列长度。子序列可以不连续,但必须保持原来的先后顺序。

f[i][j] 表示 a 的前 i 个元素与 b 的前 j 个元素的最长公共子序列长度:

  • max(f[i-1][j], f[i][j-1]):不选 a[i] 或不选 b[j]。
  • 当 a[i] == b[j] 时,还可以将这一对元素接在之前的公共子序列后面,得到 f[i-1][j-1] + 1。

因此,输出的 f[n][n] 满足:

选项判断原因
A.小于等于 \(n\)正确两个数组都只有 \(n\) 个元素,公共子序列长度最多为 \(n\)
B.大于等于 \(0\)正确长度不可能为负数;全局数组 f 初始也全部为 \(0\)
C.不一定大于等于 \(1\)正确两个数组可能没有相同元素,此时答案为 \(0\)

例如,n = 1,a = [1],b = [2],程序输出 0。所以 C 也成立,选 D。

真题版权归 CCF 所有,本站仅用于非商业教学用途。页面加载后可直接在线作答,作答记录保存在本浏览器或账号中。 京ICP备2026056990号-1 京公网安备11010502062986号