POJ - 1088 滑雪

题目大意:给出一个图,求图上的一条最长的下降路径。

解题思路:很经典的DP,求二维的最长下降子序列。用记忆化的搜索,构造以每个点为起点的最长下降路径,结合DP的状态方程:DP[i][j] = max(DP[i-1][j], DP[i+1][j], DP[i][j-1], DP[i][j+1]) + 1。(if map[i][j] > map[x][y]  && (x,y) in the map)。

#include <cstdio>
#include <algorithm>
using  namespace std;

struct Point {
    int x, y, h;
    bool operator < (const Point a) const {
        return h < a.h;
    }
} A[10010];

int main() {
    int R, C, M[110][110][2];
    int dx[4] = {1, -1, 0, 0};
    int dy[4] = {0, 0, -1, 1};
    while (scanf("%d%d", &R, &C) != EOF) {
        for (int i = 0; i < R; i++)
            for (int j = 0; j < C; j++) {
                scanf("%d", &M[i][j][0]);
                M[i][j][1] = 1;
                A[i*C+j].h = M[i][j][0];
                A[i*C+j].x = i;
                A[i*C+j].y = j;
            }

        sort(A, A + R*C);
        int ans = 1;
        for (int i = 0; i < R*C; i++) {
            int x = A[i].x, y = A[i].y;
            for (int j = 0; j < 4; j++) {
                int xx = x + dx[j], yy = y + dy[j];
                if (xx >= 0 && xx < R && yy >= 0 && yy < C && M[x][y][0] > M[xx][yy][0])
                    M[x][y][1] = max(M[x][y][1], M[xx][yy][1] + 1);
            }
            ans = max(ans, M[x][y][1]);
        }

        printf("%d\n", ans);
    }
    return 0;
}

你可能感兴趣的:(POJ - 1088 滑雪)