POJ 1088 滑雪
作者:互联网
题目描述
给定一个二维矩阵, 求该矩阵中的最长下降子序列, 该序列的路径可以是上下左右四个方向.
思路分析
记忆化搜索. 先通过dfs遍历4个方向的最长下降子序列, 然后通过记录遍历过的值进行剪枝, 因为dfs过程中会出现重复遍历的情况.
dp[i][j]
表示以矩阵中坐标为(i,j)
的元素为起点的最长下降子序列, dfs的过程中如果遍历到已经处理过的点(i,j)
(即dp[i][j] != 0
)则直接返回当前dp[i][j]
的值, 从而避免重复遍历.
Code
#include <cstdio>
#include <cstring>
const int maxn = 105;
int r, c;
int mat[maxn][maxn];
int dp[maxn][maxn];
int ans = 0;
int getMax(int a, int b) {
return a > b ? a : b;
}
int dfs(int x, int y) {
int tmp = 1;
if (dp[x][y] != 0) {
return dp[x][y];
}
if (x - 1 >= 0 && mat[x - 1][y] < mat[x][y]) {
tmp = getMax(dfs(x - 1, y) + 1, tmp);
}
if (x + 1 < r && mat[x + 1][y] < mat[x][y]) {
tmp = getMax(dfs(x + 1, y) + 1, tmp);
}
if (y - 1 >= 0 && mat[x][y - 1] < mat[x][y]) {
tmp = getMax(dfs(x, y - 1) + 1, tmp);
}
if (y + 1 < c && mat[x][y + 1] < mat[x][y]) {
tmp = getMax(dfs(x, y + 1) + 1, tmp);
}
dp[x][y] = tmp;
return tmp;
}
int main() {
scanf("%d%d", &r, &c);
memset(dp, 0, sizeof(dp));
for (int i = 0; i < r; ++i) {
for (int j = 0; j < c; ++j) {
scanf("%d", &mat[i][j]);
}
}
for (int i = 0; i < r; ++i) {
for (int j = 0; j < c; ++j) {
ans = getMax(ans, dfs(i, j));
}
}
printf("%d\n", ans);
return 0;
}
标签:tmp,mat,int,dfs,1088,POJ,getMax,滑雪,dp 来源: https://blog.csdn.net/fxyburan/article/details/102541902