Description
Michael喜欢滑雪百这并不奇怪,因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个区域中最长底滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子
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
一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-...-3-2-1更长。事实上,这是最长的一条。
Input
输入的第一行表示区域的行数R和列数C(1
<= R,C <=
100)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。
Output
输出最长区域的长度。
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
Sample Output
25
这道题据说是一道很经典的dp入门题,我从2月份看到这个题,觉得好麻烦就一直没有做,一直拖到3月,心里一直觉得过不去,终于开始做。
其实觉得思路还是很清楚的,只是不知道应该怎样用代码实现。
我的做法是用一个二维数组储存原始数据,然后对每个点调用一个递归函数,寻找周围四个方向的最长路径,加1作为这个点的最长路径。递归的方法是,对周围的四个点,如果点在地图内且高度下降,再找这个点的四个方向上的点,于是当达到边界或是某点已经被计算过,递归结束,返回最长路径值。所以这里还用到了记忆化搜索,对于每个点,都要记录这个点的最长路径值,这样就避免重复计算,是一种用空间换时间的做法。
对地图中的每个点都要调用子函数递归计算该点可以达到的路径最大值。然后比较出一个最大的作为该地图的最长路径。
要注意地图边界条件的限制,不要把行和列弄混了。
我做完之后输出数据一直有错误,后来把三个全局变量改成局部变量之后就对了。虽然我用了局部调试看了各变量值的变化,但是竟然没有意识到值的变化又问题……纠结了两个晚上,教训啊……
附代码…… 写的不好,还希望多多指教啊
#include
#include
#define MAX 100 + 10
int r, c; //行和列
int i, j;
int map[MAX][MAX]; //储存初始数据
int high[MAX][MAX] = {0}; //记忆路径值
int dx[4] = {0, 0, 1,-1}, //枚举四个方向
dy[4] = {1,-1, 0, 0};
int inarea (int x, int y) {
return x > 0 && x <= r && y > 0 && y <= c; //判断越界
}
int root (int i, int j) {
int tx, ty; //当前位置 一定是局部变量
int k; //k一定是局部变量 如果是全局变量 递归之后k = 4 ,就会出现计算错误
int maxn = 0; //当前路径最大值
if (high[i][j] > 0) //此处路径计算过
return high[i][j];
for (k = 0; k < 4; k++) { //枚举四个方向
tx = i + dx[k]; // 当前x
ty = j + dy[k]; // 当前y
if (inarea(tx, ty) && map[tx][ty] < map[i][j]) { //当前x、y在地图内,且高度下降 high[tx][ty] = root(tx, ty);
if (root(tx, ty) > maxn)
maxn = root(tx, ty); //更新最大值
}
}
high[i][j] = maxn + 1; //加上当前点
return high[i][j];
}
int main () {
int max = 0;
scanf ("%d%d", &r, &c); //输入行、列
for (i = 1; i <= r; i++)
for (j = 1; j <= c; j++)
scanf ("%d", &map[i][j]); //输入地图
for (i = 1; i <= r; i++)
for (j = 1; j <= c; j++) //对每个点调用子函数递归计算路径
if (root(i, j) > max)
max = high[i][j]; //记录最大路径
printf ("%d\n", max);
//system ("pause");
return 0;
}
这道题还有一种做法,是用一维数组储存原始数据,然后用qsort直接按从高到低排好序。但是这种做法要用到结构体,有兴趣的同学可以尝试一下。
我好菜的…… 写的不好不要批评的太严厉啊……谢谢啦~