📌  相关文章
📜  最小跳跃到达矩阵中的最后一个建筑物

📅  最后修改于: 2021-04-23 21:09:42             🧑  作者: Mango

给定一个包含整数值的矩阵,其中矩阵的每个单元格代表建筑物的高度。查找从第一个建筑物(0,0)到最后一个建筑物(n-1,m-1)所需的最小跳跃。从一个单元格跳到下一个单元格是两个建筑物高度之间的绝对差。
例子 :

Input :  int height[][] = {{ 5, 4, 2 },
                           { 9, 2, 1 },
                           { 2, 5, 9 },
                           { 1, 3, 11}}; 
Output : 12
The minimum jump path is 5 -> 2 -> 5
-> 11. Total jumps is 3 + 3 + 6 = 12.

天真的递归解决方案:
通过使用递归可以轻松解决上述问题。到达(m,n)的路径必须通过以下三个单元之一:(m-1,n-1)或(m-1,n)或(m,n-1)。因此,达到(m,n)的最小跳变可以写为“ 3个单元的最小跳变加上当前跳变”。
下面是该方法的实现。

C++
// Recursive CPP program to find minimum jumps
// to reach last building from first.
#include 
using namespace std;
 
# define R 4
# define C 3
 
bool isSafe(int x, int y)
{
    return (x < R && y < C);
}
 
/* Returns minimum jump path from (0, 0) to
  (m, n) in hight[R][C]*/
int minJump(int height[R][C], int x, int y)
{
    // base case
    if (x == R - 1 && y == C - 1)
        return 0;
 
    // Find minimum jumps if we go through diagonal
    int diag = INT_MAX;
    if (isSafe(x + 1, y + 1))
        diag = minJump(height, x + 1, y + 1) +
           abs(height[x][y] - height[x + 1][y + 1]);
 
    // Find minimum jumps if we go through down
    int down = INT_MAX;
    if (isSafe(x + 1, y))
        down = minJump(height, x + 1, y) +
             abs(height[x][y] - height[x + 1][y]);
 
    // Find minimum jumps if we go through right
    int right = INT_MAX;
    if (isSafe(x, y + 1))
        right = minJump(height, x, y + 1) +
              abs(height[x][y] - height[x][y + 1]);
 
    // return minimum jumps
    return min({down, right, diag});
}
 
/* Driver program to test above functions */
int main()
{
    int height[][C] = { { 5, 4, 2 },
                       { 9, 2, 1 },
                       { 2, 5, 9 },
                       { 1, 3, 11 } };
 
    cout << minJump(height, 0, 0);
    return 0;
}


Java
// Recursive Java program
// to find minimum jumps
// to reach last building
// from first.
class GFG {
     
    static boolean isSafe(int x, int y)
    {
        return (x < 4 && y < 3);
    }
     
    // Returns minimum jump
    // path from (0, 0) to
    // (m, n) in hight[R][C]
    static int minJump(int height[][], int x,
                                       int y)
    {
        // base case
        if (x == 4 - 1 && y == 3 - 1)
            return 0;
     
        // Find minimum jumps
        // if we go through
        // diagonal
        int diag = Integer.MAX_VALUE;
         
        if (isSafe(x + 1, y + 1))
            diag = minJump(height, x + 1, y + 1) +
                   Math.abs(height[x][y] - height[x + 1][y + 1]);
     
        // Find minimum jumps
        // if we go through
        // down
        int down = Integer.MAX_VALUE;
         
        if (isSafe(x + 1, y))
            down = minJump(height, x + 1, y) +
                   Math.abs(height[x][y] - height[x + 1][y]);
     
        // Find minimum jumps
        // if we go through right
        int right = Integer.MAX_VALUE;
         
        if (isSafe(x, y + 1))
            right = minJump(height, x, y + 1) +
                    Math.abs(height[x][y] - height[x][y + 1]);
     
        // return minimum jumps
        return Math.min(down, Math.min(right, diag));
    }
     
    // Driver program
    public static void main(String[] args)
    {
        int height[][] = { { 5, 4, 2 },
                           { 9, 2, 1 },
                           { 2, 5, 9 },
                           { 1, 3, 11} };
     
        System.out.println(minJump(height, 0, 0));
    }
}
 
// This article is contributed by Prerna Saini.


Python3
# Recursive Python3 program to find minimum jumps
# to reach last building from first.
R = 4
C = 3
 
def isSafe(x, y):
    return (x < R and y < C)
 
# Returns minimum jump path from
# (0, 0) to (m, n) in hight[R][C]
def minJump(height, x, y):
 
    # base case
    if (x == R - 1 and y == C - 1):
        return 0
 
    # Find minimum jumps if we go
    # through diagonal
    diag = 10**9
    if (isSafe(x + 1, y + 1)):
        diag = (minJump(height, x + 1, y + 1) +
                    abs(height[x][y] -
                        height[x + 1][y + 1]))
 
    # Find minimum jumps if we go through down
    down = 10**9
    if (isSafe(x + 1, y)):
        down = (minJump(height, x + 1, y) +
                    abs(height[x][y] -
                        height[x + 1][y]))
 
    # Find minimum jumps if we go through right
    right = 10**9
    if (isSafe(x, y + 1)):
        right = (minJump(height, x, y + 1) +
                     abs(height[x][y] -
                         height[x][y + 1]))
 
    # return minimum jumps
    return min([down, right, diag])
 
# Driver Code
height = [ [ 5, 4, 2 ],
           [ 9, 2, 1 ],
           [ 2, 5, 9 ],
           [ 1, 3, 11 ] ]
 
print(minJump(height, 0, 0))
 
# This code is contributed by mohit kumar


C#
// Recursive C# program
// to find minimum jumps
// to reach last building
// from first.
using System;
 
class GFG {
     
    static bool isSafe(int x, int y)
    {
        return (x < 4 && y < 3);
    }
     
    // Returns minimum jump
    // path from (0, 0) to
    // (m, n) in hight[R][C]
    static int minJump(int [,]height,
                       int x, int y)
    {
         
        // base case
        if (x == 4 - 1 && y == 3 - 1)
            return 0;
     
        // Find minimum jumps
        // if we go through
        // diagonal
        int diag = int.MaxValue;
         
        if (isSafe(x + 1, y + 1))
            diag = minJump(height, x + 1, y + 1) +
                   Math.Abs(height[x,y] -
                   height[x + 1,y + 1]);
     
        // Find minimum jumps
        // if we go through
        // down
        int down = int.MaxValue;
         
        if (isSafe(x + 1, y))
            down = minJump(height, x + 1, y) +
                   Math.Abs(height[x,y] -
                   height[x + 1,y]);
     
        // Find minimum jumps
        // if we go through right
        int right = int.MaxValue;
         
        if (isSafe(x, y + 1))
            right = minJump(height, x, y + 1) +
                    Math.Abs(height[x,y] -
                    height[x,y + 1]);
     
        // return minimum jumps
        return Math.Min(down, Math.Min(right, diag));
    }
     
    // Driver code
    public static void Main()
    {
        int [,]height = {{5, 4, 2},
                        {9, 2, 1},
                        {2, 5, 9},
                        {1, 3, 11}};
     
        Console.Write(minJump(height, 0, 0));
    }
}
 
// This code is contributed by nitin mittal


PHP


Javascript


C++
// A Dynamic Programming based CPP program to find
// minimum jumps to reach last building from first.
#include 
using namespace std;
 
#define R 4
#define C 3
 
bool isSafe(int x, int y)
{
    return (x < R && y < C);
}
 
// Lookup table used for memoization.
int dp[R][C];
 
/* Returns minimum jump path from (0, 0) to (m, n)
   in hight[R][C]*/
int minJump(int height[R][C], int x, int y)
{
    // if we visited it before
    if (dp[x][y] != -1)
        return dp[x][y];
 
    if (x == R - 1 && y == C - 1)
        return (dp[x][y] = 0);
 
    // Find minimum jumps if we go through diagonal
    int diag = INT_MAX;
    if (isSafe(x + 1, y + 1))
        diag = minJump(height, x + 1, y + 1) +
           abs(height[x][y] - height[x + 1][y + 1]);
 
    // Find minimum jumps if we go through down
    int down = INT_MAX;
    if (isSafe(x + 1, y))
        down = minJump(height, x + 1, y) +
             abs(height[x][y] - height[x + 1][y]);
 
    // Find minimum jumps if we go through right
    int right = INT_MAX;
    if (isSafe(x, y + 1))
        right = minJump(height, x, y + 1) +
              abs(height[x][y] - height[x][y + 1]);
 
    // return minimum jump
    dp[x][y] = min({down, right, diag});
    return dp[x][y];
}
 
/* Driver program to test above functions */
 
int main()
{
    int height[][C] = { { 5, 4, 2 },
                       { 9, 2, 1 },
                       { 2, 5, 9 },
                       { 1, 3, 11 } };
    memset(dp, -1, sizeof(dp));
    cout << minJump(height, 0, 0);
    return 0;
}


Java
// A Dynamic Programming based Java program to find
// minimum jumps to reach last building from first.
import java.util.*;
 
class GFG
{
 
    static int R = 4;
    static int C = 3;
 
    static boolean isSafe(int x, int y)
    {
        return (x < R && y < C);
    }
 
    // Lookup table used for memoization.
    static int[][] dp = new int[R][C];
 
    /* Returns minimum jump path from (0, 0) to (m, n)
    in hight[R][C]*/
    static int minJump(int height[][], int x, int y)
    {
        // if we visited it before
        if (dp[x][y] != -1)
        {
            return dp[x][y];
        }
 
        if (x == R - 1 && y == C - 1)
        {
            return (dp[x][y] = 0);
        }
 
        // Find minimum jumps if we go through diagonal
        int diag = Integer.MAX_VALUE;
        if (isSafe(x + 1, y + 1))
        {
            diag = minJump(height, x + 1, y + 1)
                    + Math.abs(height[x][y] - height[x + 1][y + 1]);
        }
 
        // Find minimum jumps if we go through down
        int down = Integer.MAX_VALUE;
        if (isSafe(x + 1, y))
        {
            down = minJump(height, x + 1, y)
                    + Math.abs(height[x][y] - height[x + 1][y]);
        }
 
        // Find minimum jumps if we go through right
        int right = Integer.MAX_VALUE;
        if (isSafe(x, y + 1))
        {
            right = minJump(height, x, y + 1)
                    + Math.abs(height[x][y] - height[x][y + 1]);
        }
 
        // return minimum jump
        dp[x][y] = Math.min(Math.min(down, right), diag);
        return dp[x][y];
    }
 
    /* Driver program to test above functions */
    public static void main(String[] args)
    {
        int height[][] = {{5, 4, 2},
        {9, 2, 1},
        {2, 5, 9},
        {1, 3, 11}};
        for (int i = 0; i < R; i++) {
            for (int j = 0; j < C; j++) {
                dp[i][j] = -1;
            }
        }
        System.out.println(minJump(height, 0, 0));
    }
}
 
/* This code is contributed by PrinciRaj1992 */


Python
# A Dynamic Programming based Python program to find
# minimum jumps to reach last building from first.
 
R = 4
C = 3
 
def isSafe( x, y):
 
    return (x < R and y < C)
 
# Lookup table used for memoization.
dp = [[-1 for i in range(C)] for i in range(R)]
 
# Returns minimum jump path from (0, 0) to (m, n)
# in hight[R][C]*/
def minJump(height, x, y):
 
 
# if we visited it before
    if (dp[x][y] != -1):
        return dp[x][y]
 
    if (x == R - 1 and y == C - 1):
        return (dp[x][y] == 0)
 
# Find minimum jumps if we go through diagonal
    diag = 10**9
    if (isSafe(x + 1, y + 1)):
        diag = minJump(height, x + 1, y + 1) + abs(height[x][y] - height[x + 1][y + 1])
 
# Find minimum jumps if we go through down
    down =10**9
    if (isSafe(x + 1, y)):
        down = minJump(height, x + 1, y) + abs(height[x][y] - height[x + 1][y])
 
# Find minimum jumps if we go through right
    right =10**9
    if (isSafe(x, y + 1)):
        right = minJump(height, x, y + 1) + abs(height[x][y] - height[x][y + 1])
 
# return minimum jump
    dp[x][y] = min(down, right, diag)
    return dp[x][y]
 
# Driver code
 
height=[[ 5, 4, 2 ],
    [ 9, 2, 1 ],
    [ 2, 5, 9 ],
    [ 1, 3, 11 ]]
 
print(minJump(height, 0, 0))
 
# This code is contributed by mohit kumar 29


C#
// A Dynamic Programming based C# program to find
// minimum jumps to reach last building from first.
using System;
 
class GFG
{
 
    static int R = 4;
    static int C = 3;
 
    static Boolean isSafe(int x, int y)
    {
        return (x < R && y < C);
    }
 
    // Lookup table used for memoization.
    static int[,] dp = new int[R,C];
 
    /* Returns minimum jump path from (0, 0) to (m, n)
    in hight[R,C]*/
    static int minJump(int [,]height, int x, int y)
    {
        // if we visited it before
        if (dp[x,y] != -1)
        {
            return dp[x,y];
        }
 
        if (x == R - 1 && y == C - 1)
        {
            return (dp[x,y] = 0);
        }
 
        // Find minimum jumps if we go through diagonal
        int diag = int.MaxValue;
        if (isSafe(x + 1, y + 1))
        {
            diag = minJump(height, x + 1, y + 1)
                    + Math.Abs(height[x,y] - height[x + 1,y + 1]);
        }
 
        // Find minimum jumps if we go through down
        int down = int.MaxValue;
        if (isSafe(x + 1, y))
        {
            down = minJump(height, x + 1, y)
                    + Math.Abs(height[x,y] - height[x + 1,y]);
        }
 
        // Find minimum jumps if we go through right
        int right = int.MaxValue;
        if (isSafe(x, y + 1))
        {
            right = minJump(height, x, y + 1)
                    + Math.Abs(height[x,y] - height[x,y + 1]);
        }
 
        // return minimum jump
        dp[x,y] = Math.Min(Math.Min(down, right), diag);
        return dp[x,y];
    }
 
    /* Driver code */
    public static void Main(String[] args)
    {
        int [,]height = {{5, 4, 2},
        {9, 2, 1},
        {2, 5, 9},
        {1, 3, 11}};
        for (int i = 0; i < R; i++) {
            for (int j = 0; j < C; j++) {
                dp[i,j] = -1;
            }
        }
        Console.WriteLine(minJump(height, 0, 0));
    }
}
 
// This code is contributed by 29AjayKumar


输出 :

12

该解决方案的时间复杂度是指数级的
动态编程解决方案:
如果我们绘制上述递归解的递归树,则可以观察到重叠的子问题。由于该问题具有重叠的子问题,因此我们可以使用动态编程有效地解决它。以下是基于动态编程的解决方案。

C++

// A Dynamic Programming based CPP program to find
// minimum jumps to reach last building from first.
#include 
using namespace std;
 
#define R 4
#define C 3
 
bool isSafe(int x, int y)
{
    return (x < R && y < C);
}
 
// Lookup table used for memoization.
int dp[R][C];
 
/* Returns minimum jump path from (0, 0) to (m, n)
   in hight[R][C]*/
int minJump(int height[R][C], int x, int y)
{
    // if we visited it before
    if (dp[x][y] != -1)
        return dp[x][y];
 
    if (x == R - 1 && y == C - 1)
        return (dp[x][y] = 0);
 
    // Find minimum jumps if we go through diagonal
    int diag = INT_MAX;
    if (isSafe(x + 1, y + 1))
        diag = minJump(height, x + 1, y + 1) +
           abs(height[x][y] - height[x + 1][y + 1]);
 
    // Find minimum jumps if we go through down
    int down = INT_MAX;
    if (isSafe(x + 1, y))
        down = minJump(height, x + 1, y) +
             abs(height[x][y] - height[x + 1][y]);
 
    // Find minimum jumps if we go through right
    int right = INT_MAX;
    if (isSafe(x, y + 1))
        right = minJump(height, x, y + 1) +
              abs(height[x][y] - height[x][y + 1]);
 
    // return minimum jump
    dp[x][y] = min({down, right, diag});
    return dp[x][y];
}
 
/* Driver program to test above functions */
 
int main()
{
    int height[][C] = { { 5, 4, 2 },
                       { 9, 2, 1 },
                       { 2, 5, 9 },
                       { 1, 3, 11 } };
    memset(dp, -1, sizeof(dp));
    cout << minJump(height, 0, 0);
    return 0;
}

Java

// A Dynamic Programming based Java program to find
// minimum jumps to reach last building from first.
import java.util.*;
 
class GFG
{
 
    static int R = 4;
    static int C = 3;
 
    static boolean isSafe(int x, int y)
    {
        return (x < R && y < C);
    }
 
    // Lookup table used for memoization.
    static int[][] dp = new int[R][C];
 
    /* Returns minimum jump path from (0, 0) to (m, n)
    in hight[R][C]*/
    static int minJump(int height[][], int x, int y)
    {
        // if we visited it before
        if (dp[x][y] != -1)
        {
            return dp[x][y];
        }
 
        if (x == R - 1 && y == C - 1)
        {
            return (dp[x][y] = 0);
        }
 
        // Find minimum jumps if we go through diagonal
        int diag = Integer.MAX_VALUE;
        if (isSafe(x + 1, y + 1))
        {
            diag = minJump(height, x + 1, y + 1)
                    + Math.abs(height[x][y] - height[x + 1][y + 1]);
        }
 
        // Find minimum jumps if we go through down
        int down = Integer.MAX_VALUE;
        if (isSafe(x + 1, y))
        {
            down = minJump(height, x + 1, y)
                    + Math.abs(height[x][y] - height[x + 1][y]);
        }
 
        // Find minimum jumps if we go through right
        int right = Integer.MAX_VALUE;
        if (isSafe(x, y + 1))
        {
            right = minJump(height, x, y + 1)
                    + Math.abs(height[x][y] - height[x][y + 1]);
        }
 
        // return minimum jump
        dp[x][y] = Math.min(Math.min(down, right), diag);
        return dp[x][y];
    }
 
    /* Driver program to test above functions */
    public static void main(String[] args)
    {
        int height[][] = {{5, 4, 2},
        {9, 2, 1},
        {2, 5, 9},
        {1, 3, 11}};
        for (int i = 0; i < R; i++) {
            for (int j = 0; j < C; j++) {
                dp[i][j] = -1;
            }
        }
        System.out.println(minJump(height, 0, 0));
    }
}
 
/* This code is contributed by PrinciRaj1992 */

Python

# A Dynamic Programming based Python program to find
# minimum jumps to reach last building from first.
 
R = 4
C = 3
 
def isSafe( x, y):
 
    return (x < R and y < C)
 
# Lookup table used for memoization.
dp = [[-1 for i in range(C)] for i in range(R)]
 
# Returns minimum jump path from (0, 0) to (m, n)
# in hight[R][C]*/
def minJump(height, x, y):
 
 
# if we visited it before
    if (dp[x][y] != -1):
        return dp[x][y]
 
    if (x == R - 1 and y == C - 1):
        return (dp[x][y] == 0)
 
# Find minimum jumps if we go through diagonal
    diag = 10**9
    if (isSafe(x + 1, y + 1)):
        diag = minJump(height, x + 1, y + 1) + abs(height[x][y] - height[x + 1][y + 1])
 
# Find minimum jumps if we go through down
    down =10**9
    if (isSafe(x + 1, y)):
        down = minJump(height, x + 1, y) + abs(height[x][y] - height[x + 1][y])
 
# Find minimum jumps if we go through right
    right =10**9
    if (isSafe(x, y + 1)):
        right = minJump(height, x, y + 1) + abs(height[x][y] - height[x][y + 1])
 
# return minimum jump
    dp[x][y] = min(down, right, diag)
    return dp[x][y]
 
# Driver code
 
height=[[ 5, 4, 2 ],
    [ 9, 2, 1 ],
    [ 2, 5, 9 ],
    [ 1, 3, 11 ]]
 
print(minJump(height, 0, 0))
 
# This code is contributed by mohit kumar 29

C#

// A Dynamic Programming based C# program to find
// minimum jumps to reach last building from first.
using System;
 
class GFG
{
 
    static int R = 4;
    static int C = 3;
 
    static Boolean isSafe(int x, int y)
    {
        return (x < R && y < C);
    }
 
    // Lookup table used for memoization.
    static int[,] dp = new int[R,C];
 
    /* Returns minimum jump path from (0, 0) to (m, n)
    in hight[R,C]*/
    static int minJump(int [,]height, int x, int y)
    {
        // if we visited it before
        if (dp[x,y] != -1)
        {
            return dp[x,y];
        }
 
        if (x == R - 1 && y == C - 1)
        {
            return (dp[x,y] = 0);
        }
 
        // Find minimum jumps if we go through diagonal
        int diag = int.MaxValue;
        if (isSafe(x + 1, y + 1))
        {
            diag = minJump(height, x + 1, y + 1)
                    + Math.Abs(height[x,y] - height[x + 1,y + 1]);
        }
 
        // Find minimum jumps if we go through down
        int down = int.MaxValue;
        if (isSafe(x + 1, y))
        {
            down = minJump(height, x + 1, y)
                    + Math.Abs(height[x,y] - height[x + 1,y]);
        }
 
        // Find minimum jumps if we go through right
        int right = int.MaxValue;
        if (isSafe(x, y + 1))
        {
            right = minJump(height, x, y + 1)
                    + Math.Abs(height[x,y] - height[x,y + 1]);
        }
 
        // return minimum jump
        dp[x,y] = Math.Min(Math.Min(down, right), diag);
        return dp[x,y];
    }
 
    /* Driver code */
    public static void Main(String[] args)
    {
        int [,]height = {{5, 4, 2},
        {9, 2, 1},
        {2, 5, 9},
        {1, 3, 11}};
        for (int i = 0; i < R; i++) {
            for (int j = 0; j < C; j++) {
                dp[i,j] = -1;
            }
        }
        Console.WriteLine(minJump(height, 0, 0));
    }
}
 
// This code is contributed by 29AjayKumar

输出:

12

时间复杂度: (R * C)