两个人从矩阵的左上角到右下角的最大点数
给定一个N*M阶矩阵grid[][] ,单元格中的数字为0-9 。任务是找出当两个人从(0, 0)移动到(N-1, M-1)时,只通过向右和向下移动来收集的最大金额。如果两个人都在同一个牢房里,那么他们中只有一个人可以在那个地方取钱。
例子:
Input:
1 1 1
1 0 1
1 1 1
Output: 8
Explanation: Let 1 denote the places where person 1 collects the money and 2 denote where person 2 does so, then a possible solution is
1 1 1
2 0 1
2 2 1
Input:
0 9 9 3 3
2 9 3 3 3
0 3 3 3 3
4 1 1 1 1
Output: 52
方法:这个问题可以通过使用递归来解决,通过在每个单元格中向下和向右移动人员,并在从(0, 0)到(N-1, M-1 ) 的所有路径中找到最大路径和) .所以这个想法是找到所有可能路径的成本并找到它们中的最大值。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
const static int MAXR = 20, MAXC = 20;
int cache[MAXC][MAXR][MAXC][MAXR],
dp[MAXC][MAXR][MAXC][MAXR];
int n, m;
vector grid;
// Function to find maximum money collected
// when moving from (0, 0) to (N-1, M-1)
int maxMoney(int x1, int y1, int x2, int y2)
{
// Out of bounds of grid
if (x1 >= n || y1 >= m || x2 >= n || y2 >= m)
return 0;
if (cache[x1][y1][x2][y2] != 0)
return dp[x1][y1][x2][y2];
// Mark state as visited
cache[x1][y1][x2][y2] = 1;
// Collect money from the grid cell
int money = grid[y1][x1] - '0';
if (x1 != x2 || y1 != y2)
money += grid[y2][x2] - '0';
// Take maximum of all possibilities
return dp[x1][y1][x2][y2]
= money
+ max(
max(maxMoney(x1 + 1, y1, x2 + 1, y2),
maxMoney(x1, y1 + 1, x2 + 1, y2)),
max(maxMoney(x1 + 1, y1, x2, y2 + 1),
maxMoney(x1, y1 + 1, x2, y2 + 1)));
}
// Driver Code
int32_t main()
{
// Given Input
n = 3;
m = 3;
grid.push_back("111");
grid.push_back("101");
grid.push_back("111");
// Function Call
cout << maxMoney(0, 0, 0, 0);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
static int MAXR = 20, MAXC = 20;
static int [][][][]cache = new int[MAXC][MAXR][MAXC][MAXR];
static int [][][][]dp = new int[MAXC][MAXR][MAXC][MAXR];
static int n, m;
static Vector grid = new Vector();
// Function to find maximum money collected
// when moving from (0, 0) to (N-1, M-1)
static int maxMoney(int x1, int y1, int x2, int y2)
{
// Out of bounds of grid
if (x1 >= n || y1 >= m || x2 >= n || y2 >= m)
return 0;
if (cache[x1][y1][x2][y2] != 0)
return dp[x1][y1][x2][y2];
// Mark state as visited
cache[x1][y1][x2][y2] = 1;
// Collect money from the grid cell
int money = grid.get(y1).charAt(x1)- '0';
if (x1 != x2 || y1 != y2)
money += grid.get(y2).charAt(x2) - '0';
// Take maximum of all possibilities
return dp[x1][y1][x2][y2]
= money
+ Math.max(
Math.max(maxMoney(x1 + 1, y1, x2 + 1, y2),
maxMoney(x1, y1 + 1, x2 + 1, y2)),
Math.max(maxMoney(x1 + 1, y1, x2, y2 + 1),
maxMoney(x1, y1 + 1, x2, y2 + 1)));
}
// Driver Code
public static void main(String[] args)
{
// Given Input
n = 3;
m = 3;
grid.add("111");
grid.add("101");
grid.add("111");
// Function Call
System.out.print(maxMoney(0, 0, 0, 0));
}
}
// This code is contributed by Princi Singh
Python3
# Python3 program for the above approach
MAXR, MAXC = 20, 20
cache = [[[[0 for i in range(MAXR)] for j in range(MAXC)] for k in range(MAXR)] for l in range(MAXC)]
dp = [[[[0 for i in range(MAXR)] for j in range(MAXC)] for k in range(MAXR)] for l in range(MAXC)]
grid = []
# Function to find maximum money collected
# when moving from (0, 0) to (N-1, M-1)
def maxMoney(x1, y1, x2, y2):
# Out of bounds of grid
if (x1 >= n or y1 >= m or x2 >= n or y2 >= m):
return 0
if (cache[x1][y1][x2][y2] != 0):
return dp[x1][y1][x2][y2]
# Mark state as visited
cache[x1][y1][x2][y2] = 1
# Collect money from the grid cell
money = ord(grid[y1][x1]) - ord('0')
if (x1 != x2 or y1 != y2):
money += ord(grid[y2][x2]) - ord('0')
dp[x1][y1][x2][y2] = money + max(max(maxMoney(x1 + 1, y1, x2 + 1, y2), maxMoney(x1, y1 + 1, x2 + 1, y2)),
max(maxMoney(x1 + 1, y1, x2, y2 + 1),
maxMoney(x1, y1 + 1, x2, y2 + 1)))
# Take maximum of all possibilities
return dp[x1][y1][x2][y2]
# Given Input
n = 3
m = 3
grid.append("111")
grid.append("101")
grid.append("111")
# Function Call
print(maxMoney(0, 0, 0, 0))
# This code is contributed by suresh07.
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
public class GFG{
static int MAXR = 20, MAXC = 20;
static int [,,,]cache = new int[MAXC,MAXR,MAXC,MAXR];
static int [,,,]dp = new int[MAXC,MAXR,MAXC,MAXR];
static int n, m;
static List grid = new List();
// Function to find maximum money collected
// when moving from (0, 0) to (N-1, M-1)
static int maxMoney(int x1, int y1, int x2, int y2)
{
// Out of bounds of grid
if (x1 >= n || y1 >= m || x2 >= n || y2 >= m)
return 0;
if (cache[x1,y1,x2,y2] != 0)
return dp[x1,y1,x2,y2];
// Mark state as visited
cache[x1,y1,x2,y2] = 1;
// Collect money from the grid cell
int money = grid[y1][x1]- '0';
if (x1 != x2 || y1 != y2)
money += grid[y2][x2] - '0';
// Take maximum of all possibilities
return dp[x1,y1,x2,y2]
= money
+ Math.Max(
Math.Max(maxMoney(x1 + 1, y1, x2 + 1, y2),
maxMoney(x1, y1 + 1, x2 + 1, y2)),
Math.Max(maxMoney(x1 + 1, y1, x2, y2 + 1),
maxMoney(x1, y1 + 1, x2, y2 + 1)));
}
// Driver Code
public static void Main(String[] args)
{
// Given Input
n = 3;
m = 3;
grid.Add("111");
grid.Add("101");
grid.Add("111");
// Function Call
Console.Write(maxMoney(0, 0, 0, 0));
}
}
// This code is contributed by shikhasingrajput
Javascript
输出
8
时间复杂度: O(2 N *2 M )
辅助空间: O((N*M) 2 )