📌  相关文章
📜  检查是否可以在给定功率下穿过矩阵

📅  最后修改于: 2021-04-23 16:26:48             🧑  作者: 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中达到平方与第i行和j列恰有k迄今收集的值。
  • 我们可以写出递归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。
  • 否则,答案是最大值k,以使dp [n-1] [m-1] [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 )