📌  相关文章
📜  检查是否可能以给定的幂穿过矩阵

📅  最后修改于: 2021-09-17 07:40:54             🧑  作者: Mango

给定一个NXM矩阵,每个单元格由一个整数组成。我们有K 的初始幂,我们可以向右、向下或对角线移动。当我们移动到任何单元格时,我们会吸收 mat[i][j] 值并从您的电源中释放大量的值。如果我们的力量在任何时候变成小于 0,我们就不能从那个点走得更远。现在,我们的任务是找出从 (1, 1) 到 (n, m) 的任何路径是否可以用幂 k 覆盖。如果可能,输出我们可以吸收的最大值,否则如果没有路径打印“-1”。

例子 :

Input : N = 3, M = 3, K = 7
        mat[][] = { { 2, 3, 1 },
                    { 6, 1, 9 },
                    { 8, 2, 3 } };
Output : 6
Path (1, 1) -> (2, 2) -> (3, 3) to complete
journey to absorb 6 value.

Input : N = 3, M = 4, K = 9
        mat[][] = { 
                    { 2, 3, 4, 1 },
                    { 6, 5, 5, 3 },
                    { 5, 2, 3, 4 }
                  };
Output : -1

这个想法是使用动态规划来解决问题。
方法 :

  • 声明一个布尔 3D 矩阵,比如 dp[ ][ ][ ],具有 N*M*(K+1) 维,使得 dp[ i ][ j ][ k ] 为真,如果有可能到达 i 中的正方形到目前为止收集到的恰好是 k 值的第 th行和j 列。
  • 我们可以写出循环 dp[ i ][ j ][ k ] = true 如果
    dp[i-1][j][k-mat[i][j]] or 
    dp[i][j-1][k-mat[i][j]] or 
    dp[i-1][j-1][k-mat[i][j]] 

    即我们可以拥有的三种可能的移动。

  • 我们有基本情况 dp[0][0][0] 为真。
  • 如果 dp[n-1][m-1][k] 对于 0 和 k+1 之间的所有 k 都是假的,那么答案是 -2。
  • 否则,答案是使 dp[n-1][m-1][k] 为真的最大 k。

下面是这种方法的实现:

CPP
// CPP program to find if it is possible to cross
// the matrix with given power
#include 
#define N 105
#define R 3
#define C 4
using namespace std;
  
int maximumValue(int n, int m, int p, int grid[R][C])
{
    bool dp[N][N][N];
  
    // Initializing array dp with false value.
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            for (int k = 0; k < N; k++)
                dp[i][j][k] = false;
        }
    }
  
    // For each value of dp[i][j][k]
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            for (int k = grid[i][j]; k <= p; k++) {
  
                // For first cell and for each value of k
                if (i == 0 && j == 0) {
                    if (k == grid[i][j])
                        dp[i][j][k] = true;
                }
  
                // For first cell of each row
                else if (i == 0) {
                    dp[i][j][k] = (dp[i][j][k] || 
                        dp[i][j - 1][k - grid[i][j]]);
                }
  
                // For first cell of each column
                else if (j == 0) {
                    dp[i][j][k] = (dp[i][j][k] ||
                        dp[i - 1][j][k - grid[i][j]]);
                }
  
                // For rest of the cell
                else {
  
                    // Down movement.
                    dp[i][j][k] = (dp[i][j][k] ||
                        dp[i][j - 1][k - grid[i][j]]);
  
                    // Right movement.
                    dp[i][j][k] = (dp[i][j][k] ||
                        dp[i - 1][j][k - grid[i][j]]);
  
                    // Diagonal movement.
                    dp[i][j][k] = (dp[i][j][k] ||
                        dp[i - 1][j - 1][k - grid[i][j]]);
                }
            }
        }
    }
  
    // Finding maximum k.
    int ans = 0;
    for (ans = k; ans >= 0; ans--)
        if (dp[n - 1][m - 1][ans])
            break;
  
    return ans;
}
  
// Driver Code
int main()
{
    int n = 3, m = 4, p = 9;
    int grid[R][C] = {
        { 2, 3, 4, 1 },
        { 6, 5, 5, 3 },
        { 5, 2, 3, 4 }
    };
  
    cout << maximumValue(n, m, p, grid) << endl;
    return 0;
}


Java
// Java program to find if it 
// is possible to cross the matrix
// with given power
class GFG
{
      
static final int N = 105;
static final int R = 3;
static final int C = 4;
  
static int maximumValue(int n, int m, int p,
                                int grid[][])
{
    boolean dp[][][] = new boolean[N][N][N];
    int i, j, k;
  
    // Initializing array dp with false value.
    for (i = 0; i < N; i++) {
        for (j = 0; j < N; j++) {
            for (k = 0; k < N; k++)
                dp[i][j][k] = false;
        }
    }
  
    // For each value of dp[i][j][k]
    for (i = 0; i < n; i++) {
        for (j = 0; j < m; j++) {
            for (k = grid[i][j]; k <= p; k++) {
  
                // For first cell and for 
                // each value of k
                if (i == 0 && j == 0) {
                    if (k == grid[i][j])
                        dp[i][j][k] = true;
                }
  
                // For first cell of each row
                else if (i == 0) {
                    dp[i][j][k] = (dp[i][j][k] || 
                        dp[i][j - 1][k - grid[i][j]]);
                }
  
                // For first cell of each column
                else if (j == 0) {
                    dp[i][j][k] = (dp[i][j][k] ||
                        dp[i - 1][j][k - grid[i][j]]);
                }
  
                // For rest of the cell
                else {
  
                    // Down movement.
                    dp[i][j][k] = (dp[i][j][k] ||
                        dp[i][j - 1][k - grid[i][j]]);
  
                    // Right movement.
                    dp[i][j][k] = (dp[i][j][k] ||
                        dp[i - 1][j][k - grid[i][j]]);
  
                    // Diagonal movement.
                    dp[i][j][k] = (dp[i][j][k] ||
                        dp[i - 1][j - 1][k - grid[i][j]]);
                }
            }
        }
    }
    k = p;
      
    // Finding maximum k.
    int ans = 0;
    for (ans = k; ans >= 0; ans--)
        if (dp[n - 1][m - 1][ans])
            break;
  
    return ans;
}
  
  
// Driver code 
public static void main (String[] args)
{
    int n = 3, m = 4, p = 9;
    int grid[][] = {{ 2, 3, 4, 1 },
                    { 6, 5, 5, 3 },
                    { 5, 2, 3, 4 }};
  
    System.out.println(maximumValue(n, m, p, grid));
}
}
  
// This code is contributed by Anant Agarwal.


Python3
# Python3 program to find if it is possible to cross
# the matrix with given power
N = 105
R = 3
C = 4
  
def maximumValue(n, m, p, grid):
      
    dp = [[[False for i in range(N)] for j in range(N)] for k in range(N)]
      
    # For each value of dp[i][j][k]
    for i in range(n):
        for j in range(m):
            k = grid[i][j] 
            while(k <= p):
                  
                # For first cell and for each value of k
                if (i == 0 and j == 0):
                    if (k == grid[i][j]):
                        dp[i][j][k] = True
                  
                # For first cell of each row
                elif (i == 0):
                    dp[i][j][k] = (dp[i][j][k] or 
                    dp[i][j - 1][k - grid[i][j]])
                  
                # For first cell of each column
                elif (j == 0):
                    dp[i][j][k] = (dp[i][j][k] or 
                    dp[i - 1][j][k - grid[i][j]])
                      
                # For rest of the cell
                else:
                      
                    # Down movement.
                    dp[i][j][k] = (dp[i][j][k] or 
                    dp[i][j - 1][k - grid[i][j]])
                      
                    # Right movement.
                    dp[i][j][k] = (dp[i][j][k] or 
                    dp[i - 1][j][k - grid[i][j]])
                      
                    # Diagonal movement.
                    dp[i][j][k] = (dp[i][j][k] or 
                    dp[i - 1][j - 1][k - grid[i][j]])
                k += 1
                  
    # Finding maximum k.
    ans = k
    while(ans >= 0):
        if (dp[n - 1][m - 1][ans]):
            break
        ans -= 1
      
    return ans
  
# Driver Code
n = 3
m = 4
p = 9
grid = [[2, 3, 4, 1],[6, 5, 5, 3 ],[5, 2, 3, 4]]
  
print(maximumValue(n, m, p, grid))
  
# This code is contributed by shubhamsingh10


C#
// C# program to find if it
// is possible to cross the matrix
// with given power
using System;
  
class GFG {
  
    static int N = 105;
    // static int R = 3;
    // static int C = 4;
  
    static int maximumValue(int n, int m, int p,
                                   int[, ] grid)
    {
        bool[,, ] dp = new bool[N, N, N];
        int i, j, k;
  
        // Initializing array dp with false value.
        for (i = 0; i < N; i++) {
            for (j = 0; j < N; j++) {
                for (k = 0; k < N; k++)
                    dp[i, j, k] = false;
            }
        }
  
        // For each value of dp[i][j][k]
        for (i = 0; i < n; i++) {
            for (j = 0; j < m; j++) {
                for (k = grid[i, j]; k <= p; k++) {
  
                    // For first cell and for
                    // each value of k
                    if (i == 0 && j == 0) {
                        if (k == grid[i, j])
                            dp[i, j, k] = true;
                    }
  
                    // For first cell of each row
                    else if (i == 0) {
                        dp[i, j, k] = (dp[i, j, k] || 
                        dp[i, j - 1, k - grid[i, j]]);
                    }
  
                    // For first cell of each column
                    else if (j == 0) {
                        dp[i, j, k] = (dp[i, j, k] || 
                        dp[i - 1, j, k - grid[i, j]]);
                    }
  
                    // For rest of the cell
                    else {
  
                        // Down movement.
                        dp[i, j, k] = (dp[i, j, k] || 
                        dp[i, j - 1, k - grid[i, j]]);
  
                        // Right movement.
                        dp[i, j, k] = (dp[i, j, k] || 
                        dp[i - 1, j, k - grid[i, j]]);
  
                        // Diagonal movement.
                        dp[i, j, k] = (dp[i, j, k] ||
                        dp[i - 1, j - 1, k - grid[i, j]]);
                    }
                }
            }
        }
        k = p;
  
        // Finding maximum k.
        int ans = 0;
        for (ans = k; ans >= 0; ans--)
            if (dp[n - 1, m - 1, ans])
                break;
  
        return ans;
    }
  
    // Driver code
    public static void Main()
    {
        int n = 3, m = 4, p = 9;
        int[, ] grid = { { 2, 3, 4, 1 },
                         { 6, 5, 5, 3 },
                         { 5, 2, 3, 4 } };
  
        Console.WriteLine(maximumValue(n, m, p, grid));
    }
}
  
// This code is contributed by vt_m.


输出:

-1

时间复杂度: O(n 3 )

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程