给定一个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 现场工作专业课程和学生竞争性编程现场课程。