当前位置: 代码迷 >> 综合 >> poj - 1088 - 滑雪(dp)
  详细解决方案

poj - 1088 - 滑雪(dp)

热度:57   发布时间:2024-01-10 13:00:41.0

题意:一个R * C的矩阵(1 <= R,C <= 100),元素代表该点的高度h(0<=h<=10000),从任意点出发,每次只能走上、下、左、右,且将要到的高度要比原高度小,求最长路。

题目链接:http://poj.org/problem?id=1088

——>>设dp[i][j]表示从ij位置出发的最长路,则状态转移方程为:

dp[x][y] = max(dp[x][y], Dp(nNewX, nNewY) + 1);

时间复杂度:O(R * C)

#include <cstdio>
#include <cstring>
#include <algorithm>using std::max;const int MAXN = 100 + 10;int R, C;
int nHeight[MAXN][MAXN];
int dp[MAXN][MAXN];
int dx[] = {-1, 1,  0, 0};
int dy[] = { 0, 0, -1, 1};void Read()
{for (int i = 1; i <= R; ++i){for (int j = 1; j <= C; ++j){scanf("%d", &nHeight[i][j]);}}
}int Dp(int x, int y)
{if (dp[x][y] != -1){return dp[x][y];}int& nRet = dp[x][y];nRet = 1;for (int i = 0; i < 4; ++i){int nNewX = x + dx[i];int nNewY = y + dy[i];if (nNewX >= 1&& nNewX <= R&& nNewY >= 1&& nNewY <= C&& nHeight[nNewX][nNewY] < nHeight[x][y]){nRet = max(nRet, Dp(nNewX, nNewY) + 1);}}return nRet;
}void Solve()
{int nRet = 0;memset(dp, -1, sizeof(dp));for (int i = 1; i <= R; ++i){for (int j = 1; j <= C; ++j){if (dp[i][j] == -1){Dp(i, j);}}}for (int i = 1; i <= R; ++i){for (int j = 1; j <= C; ++j){if (dp[i][j] > nRet){nRet = dp[i][j];}}}printf("%d\n", nRet);
}int main()
{while (scanf("%d%d", &R, &C) == 2){Read();Solve();}return 0;
}