Java-通过2D数组的路径中的最大和

Java-通过2D数组的路径中的最大和,java,arrays,path,2d,sum,Java,Arrays,Path,2d,Sum,基本上我有一个类似的问题: 有一个草莓植物园,由二维方形阵列表示。每种植物(每种元素)都有许多草莓。从阵列的左上角开始,只能向右或向下移动。我需要设计一个递归方法来计算穿过花园的路径,然后输出哪条路径的草莓产量最高 我想我已经理解了非常简单的递归问题,但是这个问题已经超出了我的理解范围。就创建递归方法而言,我不确定从何处开始,也不确定从何处着手 非常感谢与代码相关的任何帮助或帮助我理解此问题背后的概念。谢谢。您可以使用。这里是类似Java的伪文档(memo、R和C被假定为max方法可用的实例变量

基本上我有一个类似的问题:

有一个草莓植物园,由二维方形阵列表示。每种植物(每种元素)都有许多草莓。从阵列的左上角开始,只能向右或向下移动。我需要设计一个递归方法来计算穿过花园的路径,然后输出哪条路径的草莓产量最高

我想我已经理解了非常简单的递归问题,但是这个问题已经超出了我的理解范围。就创建递归方法而言,我不确定从何处开始,也不确定从何处着手

非常感谢与代码相关的任何帮助或帮助我理解此问题背后的概念。谢谢。

您可以使用。这里是类似Java的伪文档(
memo
R
C
被假定为
max
方法可用的实例变量)


正如dasblinkenlight所说,实现这一点最有效的方法是使用记忆或动态编程技术。我倾向于选择动态编程,但这里我将使用纯递归

答案围绕着一个基本问题的答案:“如果我在我的领域的r行和c列的正方形中,我如何评估从左上角到这里的路径,从而使草莓的数量最大化?”

实现这一点的关键是,只有两种方法可以进入r行和c列中的绘图:要么我可以从上面进入,使用r-1行和c列中的绘图;要么我可以从侧面进入,使用r行和c-1列中的绘图。之后,您只需确保了解基本情况……这意味着,从根本上说,我的纯递归版本类似于:

int[][] field;    
int max(int r, int c) {
    //Base case
    if (r == 0 && c == 0) {
        return field[r][c];
    }
    //Assuming a positive number of strawberries in each plot, otherwise this needs
    //to be negative infinity
    int maxTop = -1, maxLeft = -1;
    //We can't come from the top if we're in the top row
    if (r != 0) {
        maxTop = field[r-1][c];
    }
    //Similarly, we can't come from the left if we're in the left column
    if (c != 0) {
        maxLeft = field[r][c-1];
    }
    //Take whichever gives you more and return..
    return Math.max(maxTop, maxLeft) + field[r][c];
}
打电话给max(r-1,c-1)获取您的答案。注意这里有很多低效的地方;通过使用动态编程(我将在下面提供)或备忘录(已经定义),您会做得更好。但是要记住的是,DP和记忆技术都是更有效的方法,它们来自于这里使用的递归原则

DP:

int-maxValue(int[][]字段){
int r=字段长度;
int c=字段[0]。长度;
int[]maxValues=新的int[r][c];
对于(int i=0;i
在这两种情况下,如果要重新创建实际路径,只需保留一个与“我是从上面来的还是从左边来的”对应的布尔值的2D表格即可?如果大多数草莓路径来自上面,则将其置为真,否则置为假。这可以使您在计算后回溯面片


请注意,这在原则上仍然是递归的:在每一步中,我们都会回顾以前的结果。我们只是碰巧缓存了我们以前的结果,这样我们就不会浪费大量的工作,我们以智能的顺序攻击子问题,这样我们就可以始终解决它们。有关动态规划的更多信息,请参见。

您可以使用DP制表方法解决此问题,使用此方法可以将空间从O(m*n)节省到O(n)。使用DP记忆,您需要m*n矩阵来存储中间值。下面是我的Python代码。希望能有所帮助

def max_path(field):
    dp = [sum(field[0][:i]) for i in range(1, len(field[0]) + 1)]
    for i in range(1, len(field)):
        for j in range(len(dp)):
            dp[j] = min(dp[j], dp[j - 1] if j > 0 else float('inf')) + field[i][j]
    return dp[-1]

它必须是递归的吗?这里的迭代会更简单。是的,它必须是递归的。好吧,dasblinkenlight的答案很好,你只需要跟踪向下或向右是否会产生更大的数字。你可能是指
返回最大值[r-1][c-1]int maxValue(int[][] field) {
    int r = field.length;
    int c = field[0].length;
    int[][] maxValues = new int[r][c];
    for (int i = 0; i < r; i++) {
        for (int j = 0; j < c; j++) {
            if (i == 0 && j == 0) {
                maxValues[i][j] = field[i][j];
            } else if (i == 0) {
                maxValues[i][j] = maxValues[i][j-1] + field[i][j];
            } else if (j == 0) {
                maxValues[i][j] = maxValues[i-1][j] + field[i][j];
            } else {
                maxValues[i][j] = Math.max(maxValues[i][j-1], maxValues[i-1][j]) + field[i][j];
            }
        }
    }
    return maxValues[r-1][c-1];
}
def max_path(field):
    dp = [sum(field[0][:i]) for i in range(1, len(field[0]) + 1)]
    for i in range(1, len(field)):
        for j in range(len(dp)):
            dp[j] = min(dp[j], dp[j - 1] if j > 0 else float('inf')) + field[i][j]
    return dp[-1]