给定一个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
最佳子结构:
问题是最小成本问题的一种变体。从(n-1,n-1)到达(0,0)的路径必须通过三个像元(i,j-1)或(i-1,j)或(i-1,j-1) 。对于m和n的每个值,将调用自上而下的递归函数,检查(m + n)是否为2的幂。如果它是2的幂,则移动到单元格(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_
}
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
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
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
16
时间复杂度: O(N 2 )
辅助空间: O(N 2 )
注意:要实现自下而上的方法,我们需要检查((m + 1)+(n + 1))是2的幂还是不是(m + n),因为移动是自上而下的命令。