解题思路:设一与输入数组对应的状态数组 dp,其值代表输入数组中此点的最长滑雪路径。使用广搜填表,最后遍历输出最大值即可。
#include#include // 输入数组、解空间const int MAX = 100;int map[MAX][MAX];int dp[MAX][MAX];int r, c;int BFS(int i, int j) { int max = -1; // 如当前坐标右侧有路,则广搜填值 if (j + 1 < c && map[i][j] > map[i][j + 1]) { if (dp[i][j + 1]) { max = max > dp[i][j + 1] ? max : dp[i][j + 1]; } else { max = max > BFS(i, j + 1) ? max : BFS(i, j + 1); } } // 向下广搜 if (i + 1 < r && map[i][j] > map[i + 1][j]) { if (dp[i + 1][j]) { max = max > dp[i + 1][j] ? max : dp[i + 1][j]; } else { max = max > BFS(i + 1, j) ? max : BFS(i + 1, j); } } // 向左广搜 if (j - 1 >= 0 && map[i][j] > map[i][j - 1]) { if (dp[i][j - 1]) { max = max > dp[i][j - 1] ? max : dp[i][j - 1]; } else { max = max > BFS(i, j - 1) ? max : BFS(i, j - 1); } } // 向上广搜 if (i - 1 >= 0 && map[i][j] > map[i - 1][j]) { if (dp[i - 1][j]) { max = max > dp[i - 1][j] ? max : dp[i - 1][j]; } else { max = max > BFS(i - 1, j) ? max : BFS(i - 1, j); } } // 如上下左右均不通,该点路径值为 1; // 否则取最大路径值加 1 if (max == -1) { dp[i][j] = 1; } else { dp[i][j] = 1 + max; } return dp[i][j];}int solve() { // 遍历所有坐标,不留死角 int ans = 0; for (int i = 0; i < r; ++i) { for (int j = 0; j < c; ++j) { // 如尚未寻访此点,从此点向四面广搜 if (!dp[i][j]) { BFS(i, j); } // 同时记录最长路径 if (dp[i][j] > ans) { ans = dp[i][j]; } } } return ans;}int main() { while (scanf("%d%d", &r, &c) != EOF) { for (int i = 0; i < r; ++i) { for (int j = 0; j < c; ++j) { scanf("%d", &map[i][j]); } } // 初始化解空间 memset(dp, 0, sizeof(dp)); printf("%d\n", solve()); } return 0;}