给定一个迷宫,它是一个N * N网格grid [] [] 。迷宫的每一个细胞包含任一数字1,2或3,其中移动定义为:
- 如果grid [i] [j] = 1,则唯一有效的移动是grid [i] [j + 1] 。
- 如果grid [i] [j] = 2,则唯一有效的移动是grid [i + 1] [j] 。
- 如果grid [i] [j] = 3,则有效移动是grid [i] [j + 1]和grid [i +1] [j] 。
现在,任务是查找从grid [0] [0]到grid [N – 1] [N – 1]的所有路径的计数,以及所有路径中的最大可能和,即当所有值都已访问时单元格加到总和中。
例子:
Input: grid[][] = {
{3, 2},
{3, 1}}
Output:
Total paths: 2
Maximum sum: 7
The two valid paths are
(0, 0) -> (0, 1) -> (1, 1) with sum as 3 + 2 + 1 = 6
and (0, 0) -> (1, 0) -> (1, 1) with sum as 3 + 3 + 1 = 7
Input: grid[][] = {
{1, 1, 3, 2, 1},
{3, 2, 2, 1, 2},
{1, 3, 3, 1, 3},
{1, 2, 3, 1, 2},
{1, 1, 1, 3, 1}}
Output:
Total paths: 4
Maximum sum: 18
方法:可以使用动态编程解决此问题。
要计算路径数,请创建一个dp [] []数组,其中dp [i] [j]将存储从grid [i] [j]到grid [N – 1] [N – 1]的路径数,并递归关系将是
- 如果grid [i] [j] = 1,则dp [i] [j] = dp [i] [j + 1]。
- 如果grid [i] [j] = 2,则dp [i] [j] = dp [i + 1] [j]。
- 如果grid [i] [j] = 1,则dp [i] [j] = dp [i] [j + 1] + dp [i +1] [j]。
并且终止条件将是当源和目标相同时,即dp [N – 1] [N – 1] = 1 。
现在,要找到最大求和路径,可以创建另一个dp [] []数组,其中dp [i] [j]将存储从grid [i] [j]到grid [N – 1]的路径的最大和。 [N – 1] ,则递归关系为
- 如果grid [i] [j] = 1,则dp [i] [j] = grid [i] [j] + dp [i] [j +1]。
- 如果grid [i] [j] = 2,则dp [i] [j] = grid [i] [j] + dp [i + 1] [j]。
- 如果grid [i] [j] = 1,则dp [i] [j] = grid [i] [j] + max(dp [i] [j + 1] + dp [i +1] [j])。
并且终止条件将再次是当源和目标相同时,即dp [N – 1] [N – 1] = grid [N – 1] [N – 1] 。
C++
// C++ implementation of the approach
#include
#define COL 5
#define ROW 5
using namespace std;
// Recursive function to return the total
// paths from grid[i][j] to grid[n - 1][n - 1]
int totalPaths(int i, int j, int n,
int grid[][COL], int dp[][COL])
{
// Out of bounds
if (i < 0 || j < 0 || i >= n || j >= n)
return 0;
// If the current state hasn't been solved before
if (dp[i][j] == -1)
{
// Only valid move is right
if (grid[i][j] == 1)
dp[i][j] = totalPaths(i, j + 1, n, grid, dp);
// Only valid move is down
else if (grid[i][j] == 2)
dp[i][j] = totalPaths(i + 1, j, n, grid, dp);
// Right and down, both are valid moves
else
dp[i][j] = totalPaths(i, j + 1, n, grid, dp)
+ totalPaths(i + 1, j, n, grid, dp);
}
return dp[i][j];
}
// Recursive function to return the maximum
// sum along the path from grid[i][j] to grid[n - 1][n - 1]
int maxSumPath(int i, int j, int n,
int grid[ROW][COL], int dp[ROW][COL])
{
// Out of bounds
if (i < 0 || j < 0 || i >= n || j >= n)
return 0;
// If the current state hasn't been solved before
if (dp[i][j] == -1)
{
// Only valid move is right
if (grid[i][j] == 1)
dp[i][j] = grid[i][j] + maxSumPath(i,
j + 1, n, grid, dp);
// Only valid move is down
else if (grid[i][j] == 2)
dp[i][j] = grid[i][j] + maxSumPath(i + 1,
j, n, grid, dp);
// Right and down, both are valid moves
else
dp[i][j] = grid[i][j]
+ max(maxSumPath(i, j + 1, n, grid, dp),
maxSumPath(i + 1, j, n, grid, dp));
}
return dp[i][j];
}
// Driver code
int main()
{
int grid[ROW][COL] = { { 1, 1, 3, 2, 1 },
{ 3, 2, 2, 1, 2 },
{ 1, 3, 3, 1, 3 },
{ 1, 2, 3, 1, 2 },
{ 1, 1, 1, 3, 1 } };
int n = ROW;
// Fill the dp[][] array with -1
int dp[ROW][COL];
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
dp[i][j] = -1;
}
// When source and destination are same
// then there is only 1 path
dp[n - 1][n - 1] = 1;
// Print the count of paths from
// grid[0][0] to grid[n - 1][n - 1]
cout<<"Total paths: "
<< totalPaths(0, 0, n, grid, dp) << endl;
// Fill the dp[][] array again with -1
//for (int i = 0; i < n; i++)
// Arrays.fill(dp[i], -1);
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
dp[i][j] = -1;
}
// When source and destination are same
// then the sum is grid[n - 1][n - 1]
dp[n - 1][n - 1] = grid[n - 1][n - 1];
// Print the maximum sum among all the paths
// from grid[0][0] to grid[n - 1][n - 1]
cout<< "Maximum sum: "
<< maxSumPath(0, 0, n, grid, dp)<
Java
// Java implementation of the approach
import java.util.Arrays;
class GFG {
// Recursive function to return the total
// paths from grid[i][j] to grid[n - 1][n - 1]
static int totalPaths(int i, int j, int n, int grid[][], int dp[][])
{
// Out of bounds
if (i < 0 || j < 0 || i >= n || j >= n)
return 0;
// If the current state hasn't been solved before
if (dp[i][j] == -1) {
// Only valid move is right
if (grid[i][j] == 1)
dp[i][j] = totalPaths(i, j + 1, n, grid, dp);
// Only valid move is down
else if (grid[i][j] == 2)
dp[i][j] = totalPaths(i + 1, j, n, grid, dp);
// Right and down, both are valid moves
else
dp[i][j] = totalPaths(i, j + 1, n, grid, dp)
+ totalPaths(i + 1, j, n, grid, dp);
}
return dp[i][j];
}
// Recursive function to return the maximum
// sum along the path from grid[i][j] to grid[n - 1][n - 1]
static int maxSumPath(int i, int j, int n, int grid[][], int dp[][])
{
// Out of bounds
if (i < 0 || j < 0 || i >= n || j >= n)
return 0;
// If the current state hasn't been solved before
if (dp[i][j] == -1) {
// Only valid move is right
if (grid[i][j] == 1)
dp[i][j] = grid[i][j] + maxSumPath(i, j + 1, n, grid, dp);
// Only valid move is down
else if (grid[i][j] == 2)
dp[i][j] = grid[i][j] + maxSumPath(i + 1, j, n, grid, dp);
// Right and down, both are valid moves
else
dp[i][j] = grid[i][j]
+ Math.max(maxSumPath(i, j + 1, n, grid, dp),
maxSumPath(i + 1, j, n, grid, dp));
}
return dp[i][j];
}
// Driver code
public static void main(String[] args)
{
int grid[][] = { { 1, 1, 3, 2, 1 },
{ 3, 2, 2, 1, 2 },
{ 1, 3, 3, 1, 3 },
{ 1, 2, 3, 1, 2 },
{ 1, 1, 1, 3, 1 } };
int n = grid.length;
// Fill the dp[][] array with -1
int dp[][] = new int[n][n];
for (int i = 0; i < n; i++)
Arrays.fill(dp[i], -1);
// When source and destination are same
// then there is only 1 path
dp[n - 1][n - 1] = 1;
// Print the count of paths from
// grid[0][0] to grid[n - 1][n - 1]
System.out.println("Total paths: "
+ totalPaths(0, 0, n, grid, dp));
// Fill the dp[][] array again with -1
for (int i = 0; i < n; i++)
Arrays.fill(dp[i], -1);
// When source and destination are same
// then the sum is grid[n - 1][n - 1]
dp[n - 1][n - 1] = grid[n - 1][n - 1];
// Print the maximum sum among all the paths
// from grid[0][0] to grid[n - 1][n - 1]
System.out.println("Maximum sum: "
+ maxSumPath(0, 0, n, grid, dp));
}
}
Python3
# Python3 implementation of the approach
# Recursive function to return the total
# paths from grid[i][j] to grid[n - 1][n - 1]
def totalPaths(i, j, n, grid, dp):
# Out of bounds
if (i < 0 or j < 0 or i >= n or j >= n):
return 0
# If the current state
# hasn't been solved before
if (dp[i][j] == -1):
# Only valid move is right
if (grid[i][j] == 1):
dp[i][j] = totalPaths(i, j + 1, n, grid, dp)
# Only valid move is down
elif (grid[i][j] == 2):
dp[i][j] = totalPaths(i + 1, j, n, grid, dp)
# Right and down, both are valid moves
else:
dp[i][j] = totalPaths(i, j + 1, n, grid, dp) +\
totalPaths(i + 1, j, n, grid, dp)
return dp[i][j]
# Recursive function to return the maximum
# sum along the path from grid[i,j] to grid[n - 1,n - 1]
def maxSumPath(i, j, n, grid, dp):
# Out of bounds
if (i < 0 or j < 0 or i >= n or j >= n):
return 0
# If the current state
# hasn't been solved before
if (dp[i][j] == -1):
# Only valid move is right
if (grid[i][j] == 1):
dp[i][j] = grid[i][j] + \
maxSumPath(i, j + 1, n, grid, dp)
# Only valid move is down
elif (grid[i][j] == 2):
dp[i][j] = grid[i][j] + \
maxSumPath(i + 1, j, n, grid, dp)
# Right and down, both are valid moves
else:
dp[i][j] = grid[i][j] + \
max(maxSumPath(i, j + 1, n, grid, dp),
maxSumPath(i + 1, j, n, grid, dp))
return dp[i][j]
# Driver code
if __name__ == '__main__':
grid = [[ 1, 1, 3, 2, 1 ],
[ 3, 2, 2, 1, 2 ],
[ 1, 3, 3, 1, 3 ],
[ 1, 2, 3, 1, 2 ],
[ 1, 1, 1, 3, 1 ]]
n = len(grid[0])
# Fill the dp[n][n] array with -1
dp= [[-1] * n] * n
# When source and destination are same
# then there is only 1 path
dp[n - 1][n - 1] = 1
# Print the count of paths from
# grid[0,0] to grid[n - 1][n - 1]
print("Total paths:",
totalPaths(0, 0, n, grid, dp))
# Fill the dp[n][n] array again with -1
dp= [[-1] * n] * n
# When source and destination are same
# then the sum is grid[n - 1][n - 1]
dp[n - 1][n - 1] = grid[n - 1][n - 1]
# Print the maximum sum among all the paths
# from grid[0,0] to grid[n - 1][n - 1]
print("Maximum sum:",
maxSumPath(0, 0, n, grid, dp))
# This code is contributed by ashutosh450
C#
// C# implementation of the approach
using System;
class GFG
{
// Recursive function to return the total
// paths from grid[i][j] to grid[n - 1][n - 1]
static int totalPaths(int i, int j, int n,
int [,]grid, int [,]dp)
{
// Out of bounds
if (i < 0 || j < 0 || i >= n || j >= n)
return 0;
// If the current state
// hasn't been solved before
if (dp[i, j] == -1)
{
// Only valid move is right
if (grid[i, j] == 1)
dp[i, j] = totalPaths(i, j + 1, n, grid, dp);
// Only valid move is down
else if (grid[i, j] == 2)
dp[i, j] = totalPaths(i + 1, j, n, grid, dp);
// Right and down, both are valid moves
else
dp[i, j] = totalPaths(i, j + 1, n, grid, dp) +
totalPaths(i + 1, j, n, grid, dp);
}
return dp[i, j];
}
// Recursive function to return the maximum
// sum along the path from grid[i,j] to grid[n - 1,n - 1]
static int maxSumPath(int i, int j, int n,
int [,]grid, int [,]dp)
{
// Out of bounds
if (i < 0 || j < 0 || i >= n || j >= n)
return 0;
// If the current state
// hasn't been solved before
if (dp[i, j] == -1)
{
// Only valid move is right
if (grid[i, j] == 1)
dp[i, j] = grid[i, j] + maxSumPath(i, j + 1,
n, grid, dp);
// Only valid move is down
else if (grid[i,j] == 2)
dp[i, j] = grid[i, j] + maxSumPath(i + 1, j,
n, grid, dp);
// Right and down, both are valid moves
else
dp[i, j] = grid[i, j] +
Math.Max(maxSumPath(i, j + 1, n, grid, dp),
maxSumPath(i + 1, j, n, grid, dp));
}
return dp[i, j];
}
// Driver code
public static void Main(String[] args)
{
int [,]grid = { { 1, 1, 3, 2, 1 },
{ 3, 2, 2, 1, 2 },
{ 1, 3, 3, 1, 3 },
{ 1, 2, 3, 1, 2 },
{ 1, 1, 1, 3, 1 } };
int n = grid.GetLength(0);
// Fill the dp[,] array with -1
int [,]dp = new int[n, n];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
dp[i, j] = -1;
// When source and destination are same
// then there is only 1 path
dp[n - 1, n - 1] = 1;
// Print the count of paths from
// grid[0,0] to grid[n - 1,n - 1]
Console.WriteLine("Total paths: " +
totalPaths(0, 0, n, grid, dp));
// Fill the dp[,] array again with -1
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
dp[i, j] = -1;
// When source and destination are same
// then the sum is grid[n - 1,n - 1]
dp[n - 1, n - 1] = grid[n - 1, n - 1];
// Print the maximum sum among all the paths
// from grid[0,0] to grid[n - 1,n - 1]
Console.WriteLine("Maximum sum: " +
maxSumPath(0, 0, n, grid, dp));
}
}
// This code is contributed by Princi Singh
Total paths: 4
Maximum sum: 18
时间复杂度: O(n 2 )
空间复杂度: O(n 2 )