1 条题解

  • 0
    @ 2026-10-26 22:50:07

    思路与算法

    按坐标排序,DP记录以某原有点结尾并消耗若干新增点时最多纳入的原有点数。两个可单调连接的点之间至少补曼哈顿距离减1个点,枚举前驱和预算转移。

    正确性说明

    在任意最优单位步序列中,按出现顺序考虑原有点,相邻两原有点需补的空位数为坐标距离减1;若途经其他原有点可纳入该链节省预算。转移覆盖所有这种链。剩余新增点总可在尾端继续向右或向上追加,所以最大原有点数加k就是最优总长度。

    复杂度

    O(n²k+n log n)时间、O(nk)空间,含排序和DP负无穷初始化。

    易错点

    新增整点不受原坐标范围限制,可以延长序列;不可把严格二维上升当成两个坐标都必须增加,某一坐标可以相等。

    参考代码(C++11)

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        int n, k;
        cin >> n >> k;
        vector<pair<long long, long long>> a(n);
        for (auto &p : a)
            cin >> p.first >> p.second;
        sort(a.begin(), a.end());
        vector<vector<int>> f(n, vector<int>(k + 1, -1000000));
        int ans = 1 + k;
        for (int i = 0; i < n; i++) {
            f[i][0] = 1;
            for (int p = 0; p < i; p++)
                if (a[p].second <= a[i].second) {
                    long long gap = a[i].first - a[p].first + a[i].second - a[p].second - 1;
                    if (gap <= k)
                        for (int j = gap; j <= k; j++)
                            f[i][j] = max(f[i][j], f[p][j - gap] + 1);
                }
            for (int j = 0; j <= k; j++)
                ans = max(ans, f[i][j] + k);
        }
        cout << ans << "\n";
    }
    
    • 1

    【22CSPJ普及组】上升点列(point)

    信息

    ID
    1917
    时间
    1000ms
    内存
    512MiB
    难度
    普及
    标签
    递交数
    0
    已通过
    0
    上传者