uva 10285 Longest Run on a Snowboard(记忆化搜索)
题目连接:10285 - Longest Run on a Snowboard
题目大意:在一块R * C的雪地上有个叫name名字的人滑雪, 每次可以从高的地方滑向低的地方, 现在要选一个地方开始滑雪, 要求可以滑动的距离最长, 输出最长值。
解题思路:可以说是DFS吧, 但是对于每个位置只遍历一次, 然后记录最优解, 下次再遇到时可直接调用最优解。
#include <stdio.h> #include <string.h> const int N = 105; const int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; int max(int a, int b) { return a > b ? a : b; } int R, C, g[N][N], rec[N][N]; char name[N]; int find(int x, int y) { if (rec[x][y]) return rec[x][y] + 1; rec[x][y] = 1; int p, q; for (int i = 0; i < 4; i++) { p = x + dir[i][0], q = y + dir[i][1]; if (p < 0 || p >= R) continue; if (q < 0 || q >= C) continue; if (g[x][y] > g[p][q]) rec[x][y] = max(find(p, q), rec[x][y]); } return rec[x][y] + 1; } void solve() { int Max = 0; memset(rec, 0, sizeof(rec)); for (int i = 0; i < R; i++) { for (int j = 0; j < C; j++) { if (!rec[i][j]) { int p, q; rec[i][j] = 1; for (int k = 0; k < 4; k++) { p = i + dir[k][0], q = j + dir[k][1]; if (p < 0 || p >= R) continue; if (q < 0 || q >= C) continue; if (g[i][j] > g[p][q]) rec[i][j] = max(find(p, q), rec[i][j]); } } if (Max < rec[i][j]) Max = rec[i][j]; } } printf("%s: %d\n", name, Max); } int main() { int cas; scanf("%d", &cas); while (cas--) { scanf("%s%d%d", name, &R, &C); for (int i = 0; i < R; i++) for (int j = 0; j < C; j++) scanf("%d", &g[i][j]); solve(); } return 0; }