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;

}


 

 

你可能感兴趣的:(long)