Problem 35: 滑雪
Time Limit:1 Ms| Memory Limit:128 MB
Difficulty:3
Description
trs喜欢滑雪。他来到了一个滑雪场,这个滑雪场是一个矩形,为了简便,我们用r行c列的矩阵来表示每块地形。为了得到更快的速度,滑行的路线必须向下倾斜。
例如样例中的那个矩形,可以从某个点滑向上下左右四个相邻的点之一。例如24-17-16-1,其实25-24-23…3-2-1更长,事实上这是最长的一条。
例如样例中的那个矩形,可以从某个点滑向上下左右四个相邻的点之一。例如24-17-16-1,其实25-24-23…3-2-1更长,事实上这是最长的一条。
Input
第1行: 两个数字r,c(1<=r,c<=100),表示矩阵的行列。
第2..r+1行:每行c个数,表示这个矩阵。
第2..r+1行:每行c个数,表示这个矩阵。
Output
仅一行: 输出1个整数,表示可以滑行的最大长度。
Sample Input
5 5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
Sample Output
25
思路:记忆化搜索(今天刚知道原来这叫记忆化搜索), 就是深搜, 但是要将搜索过的
结果保存起来下次深搜时可直接调用(优化后的递归求斐波纳锲数列),用两个二维数
len[x][y], hight[x][y]分别表示x,y可以滑的最远步数和每个点的高度, 用递归实现动归的
从小到大求值。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 100
int n, m, len[MAX][MAX], hight[MAX][MAX], dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
int dfs(int x, int y)
{
if(len[x][y] != 0)
{
return len[x][y];
}
int max = 0, t, tx, ty; //每次搜索之前将到(x,y)的最长路径长度max赋为0
for(int i = 0; i < 4; i++) //搜四个方向找出最长路径
{
tx = x + dir[i][0];
ty = y + dir[i][1];
if(tx >= 0 && tx < n && ty >= 0 && ty < m && hight[tx][ty] < hight[x][y])
{
t = dfs(tx, ty); //记录此方向的最长路径
if(t > max)
{
max = t; //刷新最长路径
}
}
}
len[x][y] = max + 1; //此点最长路径为max+1
return max + 1; //返回此点最长路径,供上级调用
}
int main()
{
int i, j, maxx;
while(scanf("%d%d", &n, &m) != EOF)
{
memset(len, 0, sizeof(len)); //长度清零
for(i = 0; i < n; i++)
{
for(j = 0; j < m; j++)
{
scanf("%d", &hight[i][j]);
}
}
maxx = 0;
for(i = 0; i < n; i++) //遍历所有点求最长路径
{
for(j = 0; j < m; j++)
{
len[i][j] = dfs(i, j); //调用递归函数
if(len[i][j] > maxx)
{
maxx = len[i][j];
}
}
}
printf("%d\n", maxx); //打印最长路径
}
return 0;
}