【问题标题】:Max sum path in 2D array + double two values to achieve better score2D 数组中的最大总和路径 + 将两个值加倍以获得更好的分数
【发布时间】:2026-01-22 13:00:01
【问题描述】:

我有一个二维数组,我需要找到 left bottom 可以收集的最大总和路径,并且只能从顶部和右侧移动直到结束。我在 Java 上做过(任务非常类似于 Project Euler: Problem 81):

static int maxSumPath(int[][] data) {
    final int length = data.length;

    final int[][] sumArr = new int[length][length];

    for (int row = length - 1; row >= 0; row--) {
        for (int col = 0; col < length; col++) {
            if (row == length - 1 && col == 0) {
                sumArr[row][col] = data[row][col];
            } else if (row == length - 1) {
                sumArr[row][col] = sumArr[row][col - 1] + data[row][col];
            } else if (col == 0) {
                sumArr[row][col] = sumArr[row + 1][col] + data[row][col];
            } else {
                sumArr[row][col] = Math.max(sumArr[row][col - 1], sumArr[row + 1][col]) + data[row][col];
            }
        }
    }
    return sumArr[0][length - 1];
}

例子

302

2, 0, 0

0, 3, 0

结果7

但现在我需要实现机会将该数组的任何值加倍以获得更好的分数,我只能这样做两次,并且只能将某个值加倍

示例(在此矩阵中带有* 的数字必须加倍)

3*02

2*, 0, 0

0*, 3, 0

结果12

【问题讨论】:

  • 第一部分看起来像缝雕,有一些限制,即向上和向右。在接缝雕刻中,您正在使用动态编程创建能量阵列。第二部分是选择前2个值并将它们加倍(我误解了这部分吗?)
  • @smttsp 第二部分是选择2个最大值,同时通过最大和路径并将它们加倍
  • 你能提供另一个例子吗,你的数组可以是 3x3 或者可以是任何 nxm?
  • @YCF_L 问题是写方阵算法

标签: java arrays algorithm multidimensional-array


【解决方案1】:

您可以通过在二维数组中添加第三个维度来解决这个问题,恰好是三层:

final int[][][] sumArr = new int[3][length][length]
  • 第 0 层表示在不加倍任何元素的情况下可以获得的最佳总和
  • 第 1 层表示仅将一个数字加倍即可获得的最佳总和
  • 第二层表示将两个数字加倍可以获得的最佳总和

该算法是您已有的算法的简单扩展,除了现在您需要在 if 条件的每个分支中设置三个部分和。

这是你根据上面修改的代码:

static int maxSumPath(int[][] data) {
    final int length = data.length;
    final int[][][] sumArr = new int[3][length][length];
    for (int row = length - 1; row >= 0; row--) {
        for (int col = 0; col < length; col++) {
            int val = data[row][col];
            int val2 = data[row][col] * 2;
            if (row == length - 1 && col == 0) {
                sumArr[0][row][col] = val;
                sumArr[1][row][col] = val2;
            } else if (row == length - 1) {
                sumArr[0][row][col] = sumArr[0][row][col - 1] + val;
                sumArr[1][row][col] = Math.max(
                    sumArr[1][row][col - 1] + val
                ,   sumArr[0][row][col - 1] + val2
                );
                sumArr[2][row][col] = Math.max(
                    sumArr[1][row][col - 1] + val2
                ,   sumArr[2][row][col - 1] + val
                );
            } else if (col == 0) {
                sumArr[0][row][col] = sumArr[0][row + 1][col] + val;
                sumArr[1][row][col] = Math.max(
                    sumArr[0][row + 1][col] + val2
                ,   sumArr[1][row + 1][col] + val
                );
                sumArr[2][row][col] = Math.max(
                    sumArr[1][row + 1][col] + val2
                ,   sumArr[2][row + 1][col] + val
                );
            } else {
                sumArr[0][row][col] = Math.max(
                    sumArr[0][row][col - 1], sumArr[0][row + 1][col]
                ) + data[row][col];
                sumArr[1][row][col] = Math.max(
                    Math.max(sumArr[0][row][col - 1], sumArr[0][row + 1][col]) + val2
                ,   Math.max(sumArr[1][row][col - 1], sumArr[1][row + 1][col]) + val
                );
                sumArr[2][row][col] = Math.max(
                    Math.max(sumArr[1][row][col - 1], sumArr[1][row + 1][col])+val2
                ,   Math.max(sumArr[2][row][col - 1], sumArr[2][row + 1][col])+val
                );
            }
        }
    }
    return sumArr[2][0][length - 1];
}

Demo

【讨论】:

  • “第 1 层代表仅将一个数字加倍所能获得的最佳总和” 如何知道要加倍的值是多少?
  • 我必须收集 3d array like this 但是我应该如何知道将什么值加倍 while 循环?
  • @AntonDozortsev 您尝试将您看到的每个值加倍。零层中的先验总和的构造方式使您知道到目前为止您还没有将任何值加倍。因此,您将当前值加倍,并将其写入同一行/列的第一层。然后你对第一层到第二层做同样的事情,将当前值加倍到第一层的最佳先验总和。完成后,最好的结果是在右上角的第二层。
  • 你确定上面矩阵右上角第二层的最终得分是12吗?
  • @AntonDozortsev Та нема за що! Завжди радий допомогти。
最近更新 更多