给定一个 N x N 矩阵,其中单元格 (i, j) 处的值是从单元格 (i, j) 移动到单元格 (i – 1, j – 1), (i – 1, j) 或 (i , j – 1)。您的任务是在 N x N 矩阵(基于 0 的索引)中找到从 (N – 1, N – 1) 单元格到 (0, 0) 单元格的最大成本路径。但是,您对从一个单元格到另一个单元格的移动有一些限制。如果您在 (i, j) 单元格且 (i + j) 是 2 的幂,则您只能移动到 (i – 1, j – 1) 单元格。如果 (i + j) 不是 2 的幂,那么你可以移动到 (i – 1, j) 或 (i, j – 1)
例子:
Input :[1 2 3 1
4 5 6 1
7 8 9 1
1 1 1 1]
Output: 16
The maximum cost path is:
(3, 3) -> (3, 2) -> (2, 2) -> (1, 1) -> (0, 0).
Cost pathwise is:
1 + 1 + 9 + 5 = 16.
Input: [1 2
3 4]
Output: 4
最优子结构:
该问题是 Min-Cost 问题的变体。从 (n-1, n-1) 到达 (0, 0) 的路径必须通过三个单元格 (i, j-1) or (i-1, j) or (i-1, j-1) .将调用自顶向下的递归函数,对于 m 和 n 的每个值,检查 (m+n) 是否是 2 的幂。如果它是 2 的幂,则移动到 cell(m-1, n-1) 并将值添加到 a[m][n]。因此成本将是:
cost = a[m][n] + maxCost(a, m – 1, n – 1)
如果它不是 2 的幂,那么我们可以移动到两个单元格 (m-1, n) 和 (m, n-1)。所以成本将是:
cost = a[m][n] + max(maxCost(a, m – 1, n), maxCost(a, m, n – 1))
下面是上述方法的递归实现:
C++
// C++ program for
// SP - Wolfish
#include
using namespace std;
const int size = 1000;
// Function to find the maxCost of path from
// (n-1, n-1) to (0, 0) | recursive approach
int maxCost(int a[][size], int m, int n)
{
// base condition
if (n < 0 || m < 0)
return -1e9;
// reaches the point
else if (m == 0 && n == 0)
return 0;
else {
// i + j
int num = m + n;
// check if it is a power of 2,
// then only move diagonally
if ((num & (num - 1)) == 0)
return a[m][n] + maxCost(a, m - 1, n - 1);
// if not a power of 2
// then move side-wise
else
return a[m][n] + max(maxCost(a, m - 1, n),
maxCost(a, m, n - 1));
}
}
// Function to return the maximum cost
int answer(int a[][size], int n)
{
// calling dp function to get the answer
return maxCost(a, n - 1, n - 1);
}
// Driver Code
int main()
{
int a[][size] = { { 1, 2, 3, 1 },
{ 4, 5, 6, 1 },
{ 7, 8, 9, 1 },
{ 1, 1, 1, 1 } };
int n = 4;
// Function calling to get the answer
cout << answer(a, n);
return 0;
}
Java
// Java program for SP - Wolfish
class GFG {
static int size = 1000;
// Function to find the maxCost of path from
// (n-1, n-1) to (0, 0) | recursive approach
public static int maxCost(int[][] a, int m, int n)
{
// base condition
if (n < 0 || m < 0) {
return -1;
}
// reaches the point
else if (m == 0 && n == 0) {
return 0;
}
else {
// i + j
int num = m + n;
// check if it is a power of 2,
// then only move diagonally
if ((num & (num - 1)) == 0) {
return a[m][n] + maxCost(a, m - 1, n - 1);
}
// if not a power of 2
// then move side-wise
else {
return a[m][n] + Math.max(maxCost(a, m - 1, n), maxCost(a, m, n - 1));
}
}
}
// Function to return the maximum cost
public static int answer(int[][] a, int n)
{
// calling dp function to get the answer
return maxCost(a, n - 1, n - 1);
}
// Driver Code
public static void main(String[] args)
{
int[][] a = new int[][] { { 1, 2, 3, 1 },
{ 4, 5, 6, 1 },
{ 7, 8, 9, 1 },
{ 1, 1, 1, 1 } };
int n = 4;
System.out.println(answer(a, n));
}
}
/* This code contributed by PrinciRaj1992 */
Python3
# Python program for
# SP - Wolfish
size = 1000
# Function to find the maxCost of path from
# (n-1, n-1) to (0, 0) | recursive approach
def maxCost(a: list, m: int, n: int) -> int:
# base condition
if n < 0 or m < 0:
return int(-1e9)
# reaches the point
elif m == 0 and n == 0:
return 0
else:
# i + j
num = m + n
# check if it is a power of 2,
# then only move diagonally
if (num & (num - 1)) == 0:
return a[m][n] + maxCost(a, m - 1, n - 1)
# if not a power of 2
# then move side-wise
else:
return a[m][n] + max(maxCost(a, m - 1, n), maxCost(a, m, n - 1))
# Function to return the maximum cost
def answer(a: list, n: int) -> int:
# calling dp function to get the answer
return maxCost(a, n - 1, n - 1)
# Driver Code
if __name__ == "__main__":
a = [[1, 2, 3, 1],
[4, 5, 6, 1],
[7, 8, 9, 1],
[1, 1, 1, 1]]
n = 4
# Function calling to get the answer
print(answer(a, n))
# This code is contributed by
# sanjeev2552
C#
// C# program for
// SP - Wolfish
using System;
class GFG {
static int size = 1000;
// Function to find the maxCost of path from
// (n-1, n-1) to (0, 0) | recursive approach
public static int maxCost(int[, ] a, int m, int n)
{
// base condition
if (n < 0 || m < 0)
return -1;
// reaches the point
else if (m == 0 && n == 0)
return 0;
else {
// i + j
int num = m + n;
// check if it is a power of 2,
// then only move diagonally
if ((num & (num - 1)) == 0)
return a[m, n] + maxCost(a, m - 1, n - 1);
// if not a power of 2
// then move side-wise
else
return a[m, n] + Math.Max(maxCost(a, m - 1, n), maxCost(a, m, n - 1));
}
}
// Function to return the maximum cost
public static int answer(int[, ] a, int n)
{
// calling dp function to get the answer
return maxCost(a, n - 1, n - 1);
}
// Driver Code
static void Main()
{
int[, ] a = new int[, ] { { 1, 2, 3, 1 },
{ 4, 5, 6, 1 },
{ 7, 8, 9, 1 },
{ 1, 1, 1, 1 } };
int n = 4;
// Function calling to get the answer
Console.Write(answer(a, n));
}
// This code is contributed by DrRoot_
}
Javascript
C++
// C++ program for SP - Wolfish
#include
using namespace std;
const int size = 1000;
// Function to find the maxCost of path from
// (n-1, n-1) to (0, 0)
int maxCost(int a[][size], int m, int n, int dp[][size])
{
// base condition
if (n < 0 || m < 0)
return -1e9;
// reaches the point
else if (m == 0 && n == 0)
return 0;
// if the state has been visited previously
else if (dp[m][n] != -1)
return dp[m][n];
else {
// i + j
int num = m + n;
// check if it is a power of 2,
// then only move diagonally
if ((num & (num - 1)) == 0)
return dp[m][n] = a[m][n] + maxCost(a, m - 1, n - 1, dp);
// if not a power of 2
// then move side-wise
else
return dp[m][n] = (a[m][n] + max(maxCost(a, m - 1, n, dp),
maxCost(a, m, n - 1, dp)));
}
}
// Function to return the maximum cost
int answer(int a[][size], int n)
{
int dp[size][size];
memset(dp, -1, sizeof dp);
// calling dp function to get the answer
return maxCost(a, n - 1, n - 1, dp);
}
// Driver Code
int main()
{
int a[][size] = { { 1, 2, 3, 1 },
{ 4, 5, 6, 1 },
{ 7, 8, 9, 1 },
{ 1, 1, 1, 1 } };
int n = 4;
// Function calling to get the answer
cout << answer(a, n);
return 0;
}
Java
// Java program for SP - Wolfish
class GFG {
static int size = 1000;
// Function to find the maxCost of path from
// (n-1, n-1) to (0, 0)
static int maxCost(int a[][], int m, int n, int dp[][])
{
// base condition
if (n < 0 || m < 0)
return (int)-1e9;
// reaches the point
else if (m == 0 && n == 0)
return 0;
// if the state has been visited previously
else if (dp[m][n] != -1)
return dp[m][n];
else {
// i + j
int num = m + n;
// check if it is a power of 2,
// then only move diagonally
if ((num & (num - 1)) == 0)
return dp[m][n] = a[m][n] + maxCost(a, m - 1, n - 1, dp);
// if not a power of 2
// then move side-wise
else
return dp[m][n] = (a[m][n] + Math.max(maxCost(a, m - 1, n, dp),
maxCost(a, m, n - 1, dp)));
}
}
// Function to return the maximum cost
static int answer(int a[][], int n)
{
int dp[][] = new int[size][size];
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
dp[i][j] = -1;
}
}
// calling dp function to get the answer
return maxCost(a, n - 1, n - 1, dp);
}
// Driver Code
public static void main(String[] args)
{
int a[][] = { { 1, 2, 3, 1 },
{ 4, 5, 6, 1 },
{ 7, 8, 9, 1 },
{ 1, 1, 1, 1 } };
int n = 4;
// Function calling to get the answer
System.out.println(answer(a, n));
}
}
// This code has been contributed by 29AjayKumar
Python3
# Python program for SP - Wolfish
size = 1000;
# Function to find the maxCost of path from
# (n-1, n-1) to (0, 0)
def maxCost(a, m, n, dp):
# base condition
if (n < 0 or m < 0):
return int(-1e9);
# reaches the point
elif(m == 0 and n == 0):
return 0;
# if the state has been visited previously
elif(dp[m][n] != -1):
return dp[m][n];
else:
# i + j
num = m + n;
# check if it is a power of 2,
# then only move diagonally
if ((num & (num - 1)) == 0):
dp[m][n] = a[m][n] + maxCost(a, m - 1, n - 1, dp);
return dp[m][n];
# if not a power of 2
# then move side-wise
else:
dp[m][n] = (a[m][n] + max(maxCost(a, m - 1, n, dp), maxCost(a, m, n - 1, dp)));
return dp[m][n];
# Function to return the maximum cost
def answer(a, n):
dp = [[0 for i in range(size)] for j in range(size)] ;
for i in range(size):
for j in range(size):
dp[i][j] = -1;
# calling dp function to get the answer
return maxCost(a, n - 1, n - 1, dp);
# Driver Code
if __name__ == '__main__':
a = [[ 1, 2, 3, 1 ],[ 4, 5, 6, 1 ],[ 7, 8, 9, 1 ],[ 1, 1, 1, 1 ]];
n = 4;
# Function calling to get the answer
print(answer(a, n));
# This code contributed by Rajput-Ji
C#
// C# program for SP - Wolfish
using System;
class GFG
{
static int size = 1000;
// Function to find the maxCost of path from
// (n-1, n-1) to (0, 0)
static int maxCost(int [,]a, int m, int n, int [,]dp)
{
// base condition
if (n < 0 || m < 0)
return (int)-1e9;
// reaches the point
else if (m == 0 && n == 0)
return 0;
// if the state has been visited previously
else if (dp[m, n] != -1)
return dp[m,n];
else {
// i + j
int num = m + n;
// check if it is a power of 2,
// then only move diagonally
if ((num & (num - 1)) == 0)
return dp[m, n] = a[m, n] + maxCost(a, m - 1, n - 1, dp);
// if not a power of 2
// then move side-wise
else
return dp[m,n] = (a[m,n] + Math.Max(maxCost(a, m - 1, n, dp),
maxCost(a, m, n - 1, dp)));
}
}
// Function to return the maximum cost
static int answer(int [,]a, int n)
{
int [,]dp = new int[size,size];
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
dp[i, j] = -1;
}
}
// calling dp function to get the answer
return maxCost(a, n - 1, n - 1, dp);
}
// Driver Code
public static void Main(String[] args)
{
int [,]a = { { 1, 2, 3, 1 },
{ 4, 5, 6, 1 },
{ 7, 8, 9, 1 },
{ 1, 1, 1, 1 } };
int n = 4;
// Function calling to get the answer
Console.WriteLine(answer(a, n));
}
}
// This code contributed by Rajput-Ji
Javascript
16
时间复杂度: O(2 N )
使用记忆的方法
在上面的递归中,很多子问题被反复调用。为了减少重复调用的次数,使用了记忆功能。观察的共同点是每次函数调用时只有两个参数值在变化。因此,如果我们将返回值记忆在 dp[][] 数组中,调用次数将减少到 N^2。因此,将每个 maxCost(m, n) 的计算值存储在 dp[m][n] 中。如果 maxCost(m, n) 被多次调用,则函数的额外调用将通过返回存储在 dp[m][n] 的值来减少。
以下是上述方法的有效实现:
C++
// C++ program for SP - Wolfish
#include
using namespace std;
const int size = 1000;
// Function to find the maxCost of path from
// (n-1, n-1) to (0, 0)
int maxCost(int a[][size], int m, int n, int dp[][size])
{
// base condition
if (n < 0 || m < 0)
return -1e9;
// reaches the point
else if (m == 0 && n == 0)
return 0;
// if the state has been visited previously
else if (dp[m][n] != -1)
return dp[m][n];
else {
// i + j
int num = m + n;
// check if it is a power of 2,
// then only move diagonally
if ((num & (num - 1)) == 0)
return dp[m][n] = a[m][n] + maxCost(a, m - 1, n - 1, dp);
// if not a power of 2
// then move side-wise
else
return dp[m][n] = (a[m][n] + max(maxCost(a, m - 1, n, dp),
maxCost(a, m, n - 1, dp)));
}
}
// Function to return the maximum cost
int answer(int a[][size], int n)
{
int dp[size][size];
memset(dp, -1, sizeof dp);
// calling dp function to get the answer
return maxCost(a, n - 1, n - 1, dp);
}
// Driver Code
int main()
{
int a[][size] = { { 1, 2, 3, 1 },
{ 4, 5, 6, 1 },
{ 7, 8, 9, 1 },
{ 1, 1, 1, 1 } };
int n = 4;
// Function calling to get the answer
cout << answer(a, n);
return 0;
}
Java
// Java program for SP - Wolfish
class GFG {
static int size = 1000;
// Function to find the maxCost of path from
// (n-1, n-1) to (0, 0)
static int maxCost(int a[][], int m, int n, int dp[][])
{
// base condition
if (n < 0 || m < 0)
return (int)-1e9;
// reaches the point
else if (m == 0 && n == 0)
return 0;
// if the state has been visited previously
else if (dp[m][n] != -1)
return dp[m][n];
else {
// i + j
int num = m + n;
// check if it is a power of 2,
// then only move diagonally
if ((num & (num - 1)) == 0)
return dp[m][n] = a[m][n] + maxCost(a, m - 1, n - 1, dp);
// if not a power of 2
// then move side-wise
else
return dp[m][n] = (a[m][n] + Math.max(maxCost(a, m - 1, n, dp),
maxCost(a, m, n - 1, dp)));
}
}
// Function to return the maximum cost
static int answer(int a[][], int n)
{
int dp[][] = new int[size][size];
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
dp[i][j] = -1;
}
}
// calling dp function to get the answer
return maxCost(a, n - 1, n - 1, dp);
}
// Driver Code
public static void main(String[] args)
{
int a[][] = { { 1, 2, 3, 1 },
{ 4, 5, 6, 1 },
{ 7, 8, 9, 1 },
{ 1, 1, 1, 1 } };
int n = 4;
// Function calling to get the answer
System.out.println(answer(a, n));
}
}
// This code has been contributed by 29AjayKumar
蟒蛇3
# Python program for SP - Wolfish
size = 1000;
# Function to find the maxCost of path from
# (n-1, n-1) to (0, 0)
def maxCost(a, m, n, dp):
# base condition
if (n < 0 or m < 0):
return int(-1e9);
# reaches the point
elif(m == 0 and n == 0):
return 0;
# if the state has been visited previously
elif(dp[m][n] != -1):
return dp[m][n];
else:
# i + j
num = m + n;
# check if it is a power of 2,
# then only move diagonally
if ((num & (num - 1)) == 0):
dp[m][n] = a[m][n] + maxCost(a, m - 1, n - 1, dp);
return dp[m][n];
# if not a power of 2
# then move side-wise
else:
dp[m][n] = (a[m][n] + max(maxCost(a, m - 1, n, dp), maxCost(a, m, n - 1, dp)));
return dp[m][n];
# Function to return the maximum cost
def answer(a, n):
dp = [[0 for i in range(size)] for j in range(size)] ;
for i in range(size):
for j in range(size):
dp[i][j] = -1;
# calling dp function to get the answer
return maxCost(a, n - 1, n - 1, dp);
# Driver Code
if __name__ == '__main__':
a = [[ 1, 2, 3, 1 ],[ 4, 5, 6, 1 ],[ 7, 8, 9, 1 ],[ 1, 1, 1, 1 ]];
n = 4;
# Function calling to get the answer
print(answer(a, n));
# This code contributed by Rajput-Ji
C#
// C# program for SP - Wolfish
using System;
class GFG
{
static int size = 1000;
// Function to find the maxCost of path from
// (n-1, n-1) to (0, 0)
static int maxCost(int [,]a, int m, int n, int [,]dp)
{
// base condition
if (n < 0 || m < 0)
return (int)-1e9;
// reaches the point
else if (m == 0 && n == 0)
return 0;
// if the state has been visited previously
else if (dp[m, n] != -1)
return dp[m,n];
else {
// i + j
int num = m + n;
// check if it is a power of 2,
// then only move diagonally
if ((num & (num - 1)) == 0)
return dp[m, n] = a[m, n] + maxCost(a, m - 1, n - 1, dp);
// if not a power of 2
// then move side-wise
else
return dp[m,n] = (a[m,n] + Math.Max(maxCost(a, m - 1, n, dp),
maxCost(a, m, n - 1, dp)));
}
}
// Function to return the maximum cost
static int answer(int [,]a, int n)
{
int [,]dp = new int[size,size];
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
dp[i, j] = -1;
}
}
// calling dp function to get the answer
return maxCost(a, n - 1, n - 1, dp);
}
// Driver Code
public static void Main(String[] args)
{
int [,]a = { { 1, 2, 3, 1 },
{ 4, 5, 6, 1 },
{ 7, 8, 9, 1 },
{ 1, 1, 1, 1 } };
int n = 4;
// Function calling to get the answer
Console.WriteLine(answer(a, n));
}
}
// This code contributed by Rajput-Ji
Javascript
16
时间复杂度: O(N 2 )
辅助空间: O(N 2 )
注意:为了实现自下而上的方法,我们需要检查 ((m+1) + (n+1)) 是否是 2 的幂而不是 (m+n),因为移动是自上而下的命令。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。