查找具有数字总和的路径是最大的

时间:2014-07-30 09:20:12

标签: c++

我正在尝试找到数字总和最大的路径。它只允许在矩阵中向下和向下移动。 我编码了它,但它没有给我最大的总和,我无法弄清楚为什么它这样做! 提前致谢。

这是我的代码

 /*Given grid of positive numbers, strat from (0,0) ad end at (n,n).
   Move only to RIGHT and DOWN. Find path with sum of numbers is maximum. */

 #include<iostream>
 using namespace std;

 int grid[2][3] = { { 5, 1, 2 }, { 6, 7, 8 } };


 int max(int x, int y){
     if (x >= y){
        return x;
     }
     else if (x < y){
        return y;
     }

 }
 bool valid(int r, int c){
     if (r + 1 == 2 || c + 1 == 3)
          return false;
     else
          return true;
 }
 int maxPathSum(int row, int column){

    if (!valid(row, column))
       return 0;

 if (row == 1 && column == 2) //base condition
       return grid[row][column];

 int path1 = maxPathSum(row, column + 1); //Right
 int path2 = maxPathSum(row + 1, column); //Down

 return grid[row][column] + max(path1, path2);
}


int main()
{
    cout << maxPathSum(0, 0) << endl;
    return 0; 

}  

正确答案应为26,但输出为6.

3 个答案:

答案 0 :(得分:1)

您的函数Valid应为

bool valid (int r, int c)
{
    return r < 2 && c < 3;
}

然后你得到26Live example)。

顺便说一句,你可以使用动态编程解决这个问题。

答案 1 :(得分:0)

您还可以使用动态编程来解决问题

以下是代码:

#include <bits/stdc++.h>
using namespace std;

int grid[2][3] = { { 5, 1, 2 }, { 6, 7, 8 } };

int dp[3][4];

int main()
{
    for(int i=0;i<4;i++)
        dp[0][i] = 0;

    for(int i=0;i<3;i++)
        dp[i][0] = 0;

    for(int i=1;i<3;i++)
    {
        for(int j=1;j<4;j++)
        {
            dp[i][j] = grid[i-1][j-1] + max(dp[i][j-1], dp[i-1][j]);
        }
    }

    cout << dp[2][3];
    return 0;
}

Live example

答案 2 :(得分:0)

除DP之外,您还可以使用基于简单(n,m)矩阵的解决方案。好的方面是,这种方法将不需要DP那样的递归,如果矩阵更大并且空间复杂度仅为O(n x m),即输入数组本身,则可能导致内存问题。时间复杂度也是O(n x m)。以下Java代码演示了方法-

package com.company.dynamicProgramming;

import static java.lang.Integer.max;

public class MaxSumPathInMatrix {

    public static void main (String[] args)
    {
        int mat[][] = { { 10,  10, 2, 0,  20, 4 },
                        { 1,   0,  0, 30, 2,  5 },
                        { 200, 10, 4, 0,  2,  0 },
                        { 1,   0,  2, 20, 0,  4 }
        };

        System.out.println(findMaxSum2(mat));
    }


    /*
      Given a matrix of N * M. Find the maximum path sum in matrix.
      Find the one path having max sum - originating from (0,0) with traversal to either right or down till (N-1, M-1)
    */
    static int findMaxSum2(int mat[][])
    {
        int M = mat[0].length;
        int N = mat.length;

        for (int i = 0; i < N; i++)
        {
            for (int j = 0; j < M; j++)
            {
                if(i==0 && j!=0){
                    mat[i][j]+=mat[i][j-1];
                }
                else if(i!=0 && j==0){
                    mat[i][j]+=mat[i-1][j];
                }
                else if (i!=0 && j!=0){
                    mat[i][j]+= max(mat[i-1][j], mat[i][j-1]);
                }
            }
        }
        return mat[N-1][M-1];
    }

}

以-

的身份运行
251

Process finished with exit code 0

更进一步,即使您使用的是Dynamic Programming(DP),也要使用Memoization概念来减少时间复杂度。这是DP加上备忘录以及复杂度计算的代码-

package com.company.dynamicProgramming;

import java.util.HashMap;
import java.util.Map;

import static java.lang.Integer.max;

public class MaxSumPathInMatrix {

    static int complexity = 0;

    public static void main (String[] args)
    {
        int mat[][] = { { 10,  10, 2, 0,  20, 4 },
                        { 1,   0,  0, 30, 2,  5 },
                        { 200, 10, 4, 0,  2,  0 },
                        { 1,   0,  2, 20, 0,  4 }
        };

        System.out.println("Max Sum : " + findMaxSum2_dp(mat, 0, 0, new HashMap<>()));
        System.out.println("Time complexity : " +complexity);
    }

    /*
     ~~~> solve via ~dp~ and ~memoization~
     Given a matrix of N * M. Find the maximum path sum in matrix.
     Find the one path having max sum - originating from (0,0) with traversal to either right or down till (m-1, n-1)
    */
    static int findMaxSum2_dp(int mat[][], int i, int j, Map<String, Integer> memo){

        int M = mat[0].length;
        int N = mat.length;

        Integer sum = memo.get(i+"-"+j);
        if(sum!= null){
            return sum;
        }

        complexity++;

        if(i==N-1 && j<M-1){
            mat[i][j] += findMaxSum2_dp(mat, i, j+1, memo);
            memo.put(i+"-"+j, mat[i][j]);
            return mat[i][j];
        }
        else if(i<N-1 && j==M-1){
            mat[i][j] += findMaxSum2_dp(mat, i+1, j, memo);
            memo.put(i+"-"+j, mat[i][j]);
            return mat[i][j];
        }
        else if (i<N-1 && j<M-1){
            int s1 = findMaxSum2_dp(mat, i+1, j, memo);
            int s2 = findMaxSum2_dp(mat, i, j+1, memo);
            mat[i][j] += max(s1, s2);
            memo.put(i+"-"+j, mat[i][j]);
            return mat[i][j];
        }

        return mat[N-1][M-1] += max(mat[N-1][M-2], mat[N-2][M-1]);

    }

}

以上代码中需要注意的两个要点-

  1. 每当准备好最大和时,我会将任何子矩阵[i] [j]的最大和存储在存储区(HashMap)中。在进一步的步骤中,如果此子矩阵[i] [j]重新出现,那么我将其从存储中取出,而不是再次进行处理。作为一个例子-您可以看到[N-1] [M-1]在下面的递归图中出现了2次-
                            [N][M] = max([N][M-1]) , [N-1][M]
                                  /                  \
                                 /                    \
                                /                      \
   [N][M-1] = max ([N-1][M-1], [N][M-2])            [N-1][M] = max ([N-2][M], [N-1][M-1])

  1. 与第1点有关:我已配置了一个复杂度变量,如果我必须计算矩阵[i] [j]的最大和,即在商店中找不到该变量,则该变量会增加。如果您看到结果,则在6x4矩阵中显示25,即时间复杂度仅为O(NxM)。