简体   繁体   中英

Maximal-score path of length K in a M x N matrix

While working on a different problem, I came across this one:

Given a matrix and an integer k , find the path of length k within the matrix that maximizes the sum of the cells in the path. The path can start at any cell, can proceed in any direction, and can turn freely at each point. The path can also intersect itself, but if it does, a given cell only counts once toward the sum.

Return the sum.

In order to solve this problem I tried a recursive approach, in which for every possible starting position (ie all the elements of the matrix) I compute the longest path possible and try to use a lookup table so that repeating a certain point in the grid yield a value of 0. The problem is that I'm not sure how and when to re-initialize the lookup table so that I don't lose possible routes.

My implementation so far looks something like this.

    int maxP(int i, int j, int steps, int[][] grid) {
        if (i < 0 || i >= n || j < 0 || j >= m || steps < 0) {
            return 0;
        }
        // check if place has been passed through before
        int cost;
        if (lookup[i][j] == 1) {
           cost = 0;
        } else {
           cost = grid[i][j];
           lookup[i][j] = 1;
       }

       return cost + max(
            maxP(i - 1, j - 1, steps - 1, grid),
            maxP(i - 1, j, steps - 1, grid),
            maxP(i - 1, j + 1,steps - 1, grid),
            maxP(i, j - 1,  steps - 1, grid),
            maxP(i, j + 1, steps - 1, grid),
            maxP(i + 1, j - 1, steps - 1, grid),
            maxP(i + 1, j, steps - 1, grid),
            maxP(i + 1, j + 1, steps - 1, grid)
       );
}

The answer to "how and when to re-initialize the lookup table" is that lookup[i][j] needs to be a count of how many times a grid position is visited. When entering a grid position, increment the count. When backtracking, decrement the count. Which is to say that you never "re-initialize the lookup table" . You always maintain the table incrementally.

Here's what the modified code looks like:

int maxP(int i, int j, int steps, int[][] grid) {
    if (i < 0 || i >= n || j < 0 || j >= m || steps < 0) {
        return 0;
    }
    // check if place has been passed through before
    int cost = 0;
    if (lookup[i][j] == 0) {
        cost = grid[i][j];
    }

    // mark this place as visited
    lookup[i][j]++;

    // find the best cost recursively
    cost = cost + max(
                      maxP(i - 1, j - 1, steps - 1, grid),
                      maxP(i - 1, j, steps - 1, grid),
                      maxP(i - 1, j + 1,steps - 1, grid),
                      maxP(i, j - 1,  steps - 1, grid),
                      maxP(i, j + 1, steps - 1, grid),
                      maxP(i + 1, j - 1, steps - 1, grid),
                      maxP(i + 1, j, steps - 1, grid),
                      maxP(i + 1, j + 1, steps - 1, grid)
                      );

    // undo the change to the lookup table
    lookup[i][j]--;

    return cost;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM