给定一个N行M列的矩阵。从m[i][j],我们可以移动到m[i+1][j],如果m[i+1][j] > m[i][j],或者可以移动到m[i] [j+1] 如果 m[i][j+1] > m[i][j]。如果我们从 (0, 0) 开始,则任务是打印最长路径长度。
例子:
Input : N = 4, M = 4
m[][] = { { 1, 2, 3, 4 },
{ 2, 2, 3, 4 },
{ 3, 2, 3, 4 },
{ 4, 5, 6, 7 } };
Output : 7
Longest path is 1 2 3 4 5 6 7.
Input : N = 2, M =2
m[][] = { { 1, 2 },
{ 3, 4 } };
Output :3
Longest path is either 1 2 4 or
1 3 4.
这个想法是使用动态规划。维护二维矩阵 dp[][],其中 dp[i][j] 存储从第 i 行第 j 列开始的子矩阵的最长递增序列的长度值。
让 m[i+1][j] 和 m[i][j+1] 的最长递增子序列值分别已知为 v1 和 v2。那么 m[i][j] 的值将是 max(v1, v2) + 1。
我们可以从 m[n-1][m-1] 开始,作为基本情况,最长递增子序列的长度为 1,向上和向左移动更新单元格的值。那么单元格 m[0][0] 的 LIP 值将是答案。
下面是这个方法的实现:
C++
// CPP program to find longest increasing
// path in a matrix.
#include
#define MAX 10
using namespace std;
// Return the length of LIP in 2D matrix
int LIP(int dp[][MAX], int mat[][MAX], int n, int m, int x, int y)
{
// If value not calculated yet.
if (dp[x][y] < 0) {
int result = 0;
// If reach bottom left cell, return 1.
if (x == n - 1 && y == m - 1)
return dp[x][y] = 1;
// If reach the corner of the matrix.
if (x == n - 1 || y == m - 1)
result = 1;
// If value greater than below cell.
if (mat[x][y] < mat[x + 1][y])
result = 1 + LIP(dp, mat, n, m, x + 1, y);
// If value greater than left cell.
if (mat[x][y] < mat[x][y + 1])
result = max(result, 1 + LIP(dp, mat, n, m, x, y + 1));
dp[x][y] = result;
}
return dp[x][y];
}
// Wrapper function
int wrapper(int mat[][MAX], int n, int m)
{
int dp[MAX][MAX];
memset(dp, -1, sizeof dp);
return LIP(dp, mat, n, m, 0, 0);
}
// Driven Program
int main()
{
int mat[][MAX] = {
{ 1, 2, 3, 4 },
{ 2, 2, 3, 4 },
{ 3, 2, 3, 4 },
{ 4, 5, 6, 7 },
};
int n = 4, m = 4;
cout << wrapper(mat, n, m) << endl;
return 0;
}
Java
// Java program to find longest increasing
// path in a matrix.
import java.util.*;
class GFG {
// Return the length of LIP in 2D matrix
static int LIP(int dp[][], int mat[][], int n,
int m, int x, int y)
{
// If value not calculated yet.
if (dp[x][y] < 0) {
int result = 0;
// If reach bottom left cell, return 1.
if (x == n - 1 && y == m - 1)
return dp[x][y] = 1;
// If reach the corner of the matrix.
if (x == n - 1 || y == m - 1)
result = 1;
// If value greater than below cell.
if (x + 1 < n && mat[x][y] < mat[x + 1][y])
result = 1 + LIP(dp, mat, n, m, x + 1, y);
// If value greater than left cell.
if (y + 1 < m && mat[x][y] < mat[x][y + 1])
result = Math.max(result, 1 + LIP(dp, mat, n, m, x, y + 1));
dp[x][y] = result;
}
return dp[x][y];
}
// Wrapper function
static int wrapper(int mat[][], int n, int m)
{
int dp[][] = new int[10][10];
for (int i = 0; i < 10; i++)
Arrays.fill(dp[i], -1);
return LIP(dp, mat, n, m, 0, 0);
}
/* Driver program to test above function */
public static void main(String[] args)
{
int mat[][] = {
{ 1, 2, 3, 4 },
{ 2, 2, 3, 4 },
{ 3, 2, 3, 4 },
{ 4, 5, 6, 7 },
};
int n = 4, m = 4;
System.out.println(wrapper(mat, n, m));
}
}
// This code is contributed by Arnav Kr. Mandal.
Python3
# Python3 program to find longest
# increasing path in a matrix.
MAX = 20
# Return the length of
# LIP in 2D matrix
def LIP(dp, mat, n, m, x, y):
# If value not calculated yet.
if (dp[x][y] < 0):
result = 0
# If reach bottom left cell,
# return 1.
if (x == n - 1 and y == m - 1):
dp[x][y] = 1
return dp[x][y]
# If reach the corner
# of the matrix.
if (x == n - 1 or y == m - 1):
result = 1
# If value greater than below cell.
if (x + 1 < n and mat[x][y] < mat[x + 1][y]):
result = 1 + LIP(dp, mat, n,
m, x + 1, y)
# If value greater than left cell.
if (y + 1 < m and mat[x][y] < mat[x][y + 1]):
result = max(result, 1 + LIP(dp, mat, n,
m, x, y + 1))
dp[x][y] = result
return dp[x][y]
# Wrapper function
def wrapper(mat, n, m):
dp = [[-1 for i in range(MAX)]
for i in range(MAX)]
return LIP(dp, mat, n, m, 0, 0)
# Driver Code
mat = [[1, 2, 3, 4 ],
[2, 2, 3, 4 ],
[3, 2, 3, 4 ],
[4, 5, 6, 7 ]]
n = 4
m = 4
print(wrapper(mat, n, m))
# This code is contributed
# by Sahil Shelangia
C#
// C# program to find longest increasing
// path in a matrix.
using System;
public class GFG {
// Return the length of LIP in 2D matrix
static int LIP(int[, ] dp, int[, ] mat, int n,
int m, int x, int y)
{
// If value not calculated yet.
if (dp[x, y] < 0) {
int result = 0;
// If reach bottom left cell, return 1.
if (x == n - 1 && y == m - 1)
return dp[x, y] = 1;
// If reach the corner of the matrix.
if (x == n - 1 || y == m - 1)
result = 1;
// If value greater than below cell.
if (x + 1 < n && mat[x, y] < mat[x + 1, y])
result = 1 + LIP(dp, mat, n, m, x + 1, y);
// If value greater than left cell.
if (y + 1 < m && mat[x, y] < mat[x, y + 1])
result = Math.Max(result, 1 + LIP(dp, mat, n, m, x, y + 1));
dp[x, y] = result;
}
return dp[x, y];
}
// Wrapper function
static int wrapper(int[, ] mat, int n, int m)
{
int[, ] dp = new int[10, 10];
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
dp[i, j] = -1;
}
}
return LIP(dp, mat, n, m, 0, 0);
}
/* Driver code */
public static void Main()
{
int[, ] mat = {
{ 1, 2, 3, 4 },
{ 2, 2, 3, 4 },
{ 3, 2, 3, 4 },
{ 4, 5, 6, 7 },
};
int n = 4, m = 4;
Console.WriteLine(wrapper(mat, n, m));
}
}
/* This code contributed by PrinciRaj1992 */
Javascript
输出:
7
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。