1 条题解

  • 0
    @ 2026-7-12 17:23:47
    // 原矩阵大小最大 1000×1000,这里开 1005
    long long a[1005][1005];            // 存储每个格子的数值
    long long f[1005][1005][3];         // DP 状态,第三维 0/1/2 表示进入方式
        // 将 f 数组初始化为一个非常小的负数(近似负无穷),表示不可达
        memset(f, 0xcf, sizeof f);
    
        // 起点 (1,1) 无论从哪个方向“进入”,都只有它本身的值
        // 第三维含义:0 = 从左边来,1 = 从上边来,2 = 从下边来
        // 起点特殊处理,三个方向初始值均为 a[1][1]
        f[1][1][0] = f[1][1][1] = f[1][1][2] = a[1][1];
    
        // 按列进行动态规划(因为右移是最终方向,以列为阶段)
        for (int j = 1; j <= m; j++) {
    
            // 第一遍:处理从左边进入(即同一列内从上往下)的状态
            for (int i = 1; i <= n; i++) {
                // 状态0:从左边进入 (i,j)
                // 需要前一列 (i, j-1) 的任意状态,加上当前格子的值
                if (j > 1)
                    f[i][j][0] = max({f[i][j-1][0], f[i][j-1][1],
                                    f[i][j-1][2]}) + a[i][j];
    
                // 状态1:从上方进入 (i,j)
                // 需要同一列上一行 (i-1, j) 从左边或上方进入的状态,但不能从下方(避免回头)
                if (i > 1)
                    f[i][j][1] = max(f[i-1][j][0], f[i-1][j][1]) + a[i][j];
            }
    
            // 第二遍:处理从下方进入(即同一列内从下往上)的状态
            // 方向相反,从下往上更新
            for (int i = n - 1; i >= 1; i--) {
                // 状态2:从下方进入 (i,j)
                // 需要同一列下一行 (i+1, j) 从左边或下方进入的状态
                f[i][j][2] = max(f[i+1][j][0], f[i+1][j][2]) + a[i][j];
            }
        }
    
        // 最终答案:到达终点 (n,m) 时,可以从左边、上方或下方进入,取最大值
        cout << max({f[n][m][0], f[n][m][1], f[n][m][2]});
    
    • 1

    信息

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