其他分享
首页 > 其他分享> > POJ 1088 滑雪

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