📜  须藤放置[1.5] |狼

📅  最后修改于: 2021-05-04 22:26:26             🧑  作者: 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 

最佳子结构:
问题是最小成本问题的一种变体。从(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]。因此,成本为:

如果不是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_
}


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),因为移动是自上而下的命令。