Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 当允许向右和向下移动时,打印迷宫中从第一个单元格到最后一个单元格的最大成本的整个路径_Algorithm_Recursion_Data Structures_Dynamic Programming_Backtracking - Fatal编程技术网

Algorithm 当允许向右和向下移动时,打印迷宫中从第一个单元格到最后一个单元格的最大成本的整个路径

Algorithm 当允许向右和向下移动时,打印迷宫中从第一个单元格到最后一个单元格的最大成本的整个路径,algorithm,recursion,data-structures,dynamic-programming,backtracking,Algorithm,Recursion,Data Structures,Dynamic Programming,Backtracking,我需要一个非常流行的动态规划问题的增强帮助。最小/最大成本路径 问题:有一个2D矩阵的值为(0,1,-1) 我们需要打印收集的最大樱桃数以及收集最大樱桃数的整个路径。 input : {{0, 1, -1}, {1, 0, -1},{1,1,1}}; output : 4 (0,0) -> (1,0) -> (2,0) -> (2,1) -> (2,2) 我可以编写代码来打印收集的最大樱桃数,但无法获得如何存储整个路径的逻辑。由于我们在回溯时决定要选择哪个单元格,

我需要一个非常流行的动态规划问题的增强帮助。最小/最大成本路径

问题:有一个2D矩阵的值为(0,1,-1)

我们需要打印收集的最大樱桃数以及收集最大樱桃数的整个路径。

input : 
{{0, 1, -1}, {1, 0, -1},{1,1,1}};

output : 
4
(0,0) -> (1,0) -> (2,0) -> (2,1) -> (2,2)
我可以编写代码来打印收集的最大樱桃数,但无法获得如何存储整个路径的逻辑。由于我们在回溯时决定要选择哪个单元格,所以看起来有点困难。在这方面没有找到任何web帮助。我被困住了,任何帮助都将不胜感激

public int cherryPickup(int[][] grid) {
    if (grid.length == 0) {
        return -1;
    }
    int[][] dp = new int[grid.length][grid[0].length];
    setDp(dp);
    int forwardMax = getForwardMax(grid, dp, 0, 0);
    return forwardMax;
}

private void setDp(int[][] dp) {
    for (int i = 0; i < dp.length; i++) {
        for (int j = 0; j < dp[0].length; j++) {
            dp[i][j] = -1;
        }
    }
}

private int getForwardMax(int[][] grid, int[][] dp, int i, int j) {
    if(dp[i][j] != -1) {
        return dp[i][j];
    }
    if (grid[i][j] == -1) {
        dp[i][j] = 0;
        return dp[i][j];
    }
    if (i == grid.length - 1 && j == grid[0].length - 1) {
        dp[i][j] = grid[i][j];
        return dp[i][j];
    }
    if (i == grid.length - 1) {
        dp[i][j] = grid[i][j] + getForwardMax(grid, dp, i, j + 1);
        return dp[i][j];
    }
    if (j == grid[0].length - 1) {
        dp[i][j] = grid[i][j] + getForwardMax(grid, dp, i + 1, j);
        return dp[i][j];
    }
    dp[i][j] = grid[i][j] + Math.max(getForwardMax(grid, dp, i + 1, j), getForwardMax(grid, dp, i, j + 1));
    return dp[i][j];

}

如果您自上而下地编写动态编程(正如您所做的),恢复实际答案实际上非常容易

因此,您有一个函数
getForwardMax
,对于给定的单元格,它返回我们可以向右或向下移动收集的最大金额

您还知道起始位置,所以您需要做的就是一步一步地构建答案:

  • 假设您在某个单元格中
    (r,c)
  • 如果只有一种可能的移动方式(你在边界),就这样做
  • 否则,我们可以移动到
    (r+1,c)
    (r,c+1)
  • 我们还知道,通过移动到这些单元格并完成从
    getForwardMax
    函数到目标的路径,我们将获得多少收入
  • 所以我们只选择能带来更好结果的动作

  • 如果您自上而下地编写动态编程(正如您所做的),恢复实际答案实际上非常容易

    因此,您有一个函数
    getForwardMax
    ,对于给定的单元格,它返回我们可以向右或向下移动收集的最大金额

    您还知道起始位置,所以您需要做的就是一步一步地构建答案:

  • 假设您在某个单元格中
    (r,c)
  • 如果只有一种可能的移动方式(你在边界),就这样做
  • 否则,我们可以移动到
    (r+1,c)
    (r,c+1)
  • 我们还知道,通过移动到这些单元格并完成从
    getForwardMax
    函数到目标的路径,我们将获得多少收入
  • 所以我们只选择能带来更好结果的动作

  • 好的,自下而上的DP是一个正确的解决方案。我刚刚意识到,您不需要单独的
    path[][]
    来存储路径并对其进行迭代

    您可以使用一个简单的while循环,从right和down两个选项中选择最佳选项。 如果两者恰好具有相同的值,则不必担心,因为一个网格可能有多个正确的解决方案。因此,在发生冲突的情况下选择其中一个仍然会为您提供正确的解决方案

    • 我们从
      (0,0)
      开始
    • 如果右侧的
      dp[x][y+1]
      单元格中包含的值+当前
      网格[x][y]
      为我们提供了与
      dp[x][y]
      相同的值,则我们向右移动,否则我们向下移动
    片段:

    int x = 0,y = 0;
    
    while(x != rows-1 || y != cols-1){
        System.out.println("( " + x + " , " + y + " )");
        if(x+1 < rows && grid[x][y] + dp[x+1][y] == dp[x][y]){
            x++;
        }else if(y + 1 < cols && grid[x][y] + dp[x][y+1] == dp[x][y]){
            y++;
        }
    }
    
    System.out.println("( " + x + " , " + y + " )");
    
    intx=0,y=0;
    而(x!=行-1 | | y!=列-1){
    System.out.println(“(“+x+”,“+y+”);
    如果(x+1<行和网格[x][y]+dp[x+1][y]==dp[x][y]){
    x++;
    }如果(y+1

    完整代码:

    好的,自下而上的DP和您的一样是正确的解决方案。我刚刚意识到,您不需要单独的
    path[][]
    来存储路径并对其进行迭代

    您可以使用一个简单的while循环,从right和down两个选项中选择最佳选项。 如果两者恰好具有相同的值,则不必担心,因为一个网格可能有多个正确的解决方案。因此,在发生冲突的情况下选择其中一个仍然会为您提供正确的解决方案

    • 我们从
      (0,0)
      开始
    • 如果右侧的
      dp[x][y+1]
      单元格中包含的值+当前
      网格[x][y]
      为我们提供了与
      dp[x][y]
      相同的值,则我们向右移动,否则我们向下移动
    片段:

    int x = 0,y = 0;
    
    while(x != rows-1 || y != cols-1){
        System.out.println("( " + x + " , " + y + " )");
        if(x+1 < rows && grid[x][y] + dp[x+1][y] == dp[x][y]){
            x++;
        }else if(y + 1 < cols && grid[x][y] + dp[x][y+1] == dp[x][y]){
            y++;
        }
    }
    
    System.out.println("( " + x + " , " + y + " )");
    
    intx=0,y=0;
    而(x!=行-1 | | y!=列-1){
    System.out.println(“(“+x+”,“+y+”);
    如果(x+1<行和网格[x][y]+dp[x+1][y]==dp[x][y]){
    x++;
    }如果(y+1

    完整代码:

    任何示例案例?在descriptionok中添加了示例输入和输出,我们可以向所有4个方向移动吗?还是正好向下移动?它也是从(0,0)到(m-1,n-1)的吗?所以,因为它要么是右的,要么是下的,所以只需要保留单元格的索引,它会给你一个更高的值。您可以将它们存储在
    路径[][]
    中,稍后再打印。很抱歉,所提供的输入还不能使用。。如果我的理解不正确,请纠正我。是否会添加我从您的上述评论中提取线索编写的代码?任何示例案例?在descriptionok中添加示例输入和输出,我们是否可以向所有4个方向移动,或者它是否正好向下移动?它也是从(0,0)到(m-1,n-1)的吗?所以,因为它要么是右的,要么是下的,所以只需要保留单元格的索引,它会给你一个更高的值。您可以将它们存储在
    路径[][]
    中,稍后再打印。很抱歉,所提供的输入还不能使用。。如果我的理解不正确,请纠正我。将添加我根据上述注释编写的代码。请查看编辑后的代码。路径[][]建议的解决方案仍然不起作用。请提供帮助您可以看一下已编辑的代码..路径[][]建议的解决方案仍然不起作用。请帮忙
    int x = 0,y = 0;
    
    while(x != rows-1 || y != cols-1){
        System.out.println("( " + x + " , " + y + " )");
        if(x+1 < rows && grid[x][y] + dp[x+1][y] == dp[x][y]){
            x++;
        }else if(y + 1 < cols && grid[x][y] + dp[x][y+1] == dp[x][y]){
            y++;
        }
    }
    
    System.out.println("( " + x + " , " + y + " )");