1 条题解

  • 0
    @ 2026-4-1 13:08:44

    题目题解

    题目理解

    我们需要判断是否存在一个 n×mn \times m 的非负整数网格,使得没有一条贪婪路径(即每一步都向右或向下移动到数值更大的相邻单元格的路径)能够达到所有向下/向右路径中的最大值

    关键观察

    1. 平凡情况:n=1n = 1m=1m = 1

    当网格只有一行或一列时,从左上角到右下角只有唯一一条路径。这条路径既是贪婪路径(因为没有其他选择),也是所有路径中的最大值路径。因此,不存在满足条件的网格,输出 "NO"

    2. 特殊小网格:n=m=2n = m = 2

    2×22 \times 2 网格中,从 (1,1)(1,1)(2,2)(2,2) 只有两条路径:

    • 右 → 下:a1,1+a1,2+a2,2a_{1,1} + a_{1,2} + a_{2,2}
    • 下 → 右:a1,1+a2,1+a2,2a_{1,1} + a_{2,1} + a_{2,2}

    第一步之后,贪婪规则会选择数值更大的相邻单元格:

    • 如果 a1,2>a2,1a_{1,2} > a_{2,1},贪婪路径走右→下
    • 如果 a1,2<a2,1a_{1,2} < a_{2,1},贪婪路径走下→右
    • 如果相等,任选其一

    不难验证,贪婪路径总会选择数值较大的那条路径,因此贪婪路径必定达到最大值。所以 2×22 \times 2 网格也不存在满足条件的网格,输出 "NO"

    3. 其他所有情况:n2,m2n \ge 2, m \ge 2(n,m)(2,2)(n,m) \neq (2,2)

    对于这些情况,存在构造使得贪婪路径无法达到最大值,输出 "YES"

    构造方法

    假设 nmn \le m(否则可以转置网格),构造一个 n×mn \times m 的网格如下:

    1. 首先将所有单元格初始化为 11
    2. 修改左上角的 2×32 \times 3 子网格为:

    [ \begin{bmatrix} 1 & 3 & 2 \ 1 & 3 & 1 \end{bmatrix} ]

    即:

    • a1,1=1a_{1,1} = 1a1,2=3a_{1,2} = 3a1,3=2a_{1,3} = 2
    • a2,1=1a_{2,1} = 1a2,2=3a_{2,2} = 3a2,3=1a_{2,3} = 1
    • 其余单元格保持为 11

    验证构造的正确性

    最大值路径

    考虑路径:$(1,1) \rightarrow (2,1) \rightarrow (2,2) \rightarrow (2,3) \rightarrow \cdots \rightarrow (2,m) \rightarrow (3,m) \rightarrow \cdots \rightarrow (n,m)$

    这条路径经过:

    • (1,1)(1,1):值 11
    • 22 行所有单元格:从 (2,1)(2,1)(2,m)(2,m) 全部为 11(除了 (2,2)=3(2,2)=3(2,3)=1(2,3)=1,但 (2,2)(2,2)(2,3)(2,3) 也在其中)
    • 然后向下走到 (n,m)(n,m)

    计算这条路径的和:

    • 第一列:a1,1+a2,1=1+1=2a_{1,1} + a_{2,1} = 1 + 1 = 2
    • 第二行:包含 a2,2=3a_{2,2}=3a2,3=1a_{2,3}=1,其余为 11,共 mm 个单元格
    • 加上右下角路径上的其他单元格

    可以验证这条路径的和达到了理论最大值(因为我们在第二行收集了较大的 33,且其余位置全是 11,没有浪费)。

    贪婪路径的局限

    贪婪路径的第一步必须选择向右或向下中数值更大的邻居:

    • (1,1)(1,1) 出发,比较 a1,2=3a_{1,2}=3a2,1=1a_{2,1}=1,显然 3>13 > 1,所以贪婪路径第一步必须向右(1,2)(1,2)

    此时路径已经固定为: $(1,1) \rightarrow (1,2) \rightarrow (1,3) \rightarrow \cdots$

    由于 a1,2=3a_{1,2}=3 很大,贪婪路径被迫沿着第一行向右移动,无法进入第二行去获取 a2,2=3a_{2,2}=3(虽然两个 33 数值相等,但贪婪规则允许任选,但这里 a1,2=3a_{1,2}=3 已经很大,后续比较中可能不会转向)。

    通过具体计算可以发现,这条贪婪路径的总和严格小于上面构造的最大值路径,从而证明了不存在贪婪路径能达到全局最大值。

    时间复杂度

    • 判断条件:O(1)O(1) 每个测试用例
    • 总复杂度:O(t)O(t),满足 t5000t \le 5000 的限制

    代码实现

    #include <bits/stdc++.h>
    using namespace std;
    
    int main() {
        int t;
        cin >> t;
        while (t--) {
            int n, m;
            cin >> n >> m;
            
            // 只有一行或一列,或 2x2 网格时,所有贪婪路径都能达到最大值
            if (n == 1 || m == 1 || (n == 2 && m == 2)) {
                cout << "NO\n";
            } else {
                cout << "YES\n";
            }
        }
        return 0;
    }
    

    总结

    本题的关键在于识别出仅当网格为 1×k1 \times kk×1k \times 12×22 \times 2,贪婪路径才能保证达到全局最大值;其他情况下都可以通过巧妙构造使贪婪路径无法达到最优。这种构造利用了 2×32 \times 3 子网格中数值的巧妙分布,迫使贪婪路径在第一步就做出"错误"的选择。

    • 1

    信息

    ID
    6186
    时间
    1000ms
    内存
    256MiB
    难度
    1
    标签
    递交数
    2
    已通过
    1
    上传者