📜  须藤放置[1.5] |狼

📅  最后修改于: 2021-09-17 06:50:24             🧑  作者: Mango

给定一个 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]。因此成本将是:

如果它不是 2 的幂,那么我们可以移动到两个单元格 (m-1, n) 和 (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 现场工作专业课程学生竞争性编程现场课程