POJ1088-滑雪

滑雪摔出阴影的我一脚把题目踹上来----》

【题目描述】
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更长。事实上,这是最长的一条。

【输入】

输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。

【输出】

输出最长区域的长度。

【输入示例】

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

【输出示例】

25

 

第一眼我仍然把它看成深搜,但是看了数据范围之后我就和深搜说拜拜。

嗯,我只好拿出我刚学不到两天的记忆化搜索来凑数。

现在我们来把程序拆解一下:

思路:计算每个点到山脚的最长路程。

 1 int up=0,down=0,left=0,right=0;
 2     if(x-1>0)
 3     {
 4         if(map[x-1][y]<map[x][y])
 5         {
 6             up=snow(x-1,y)+1;
 7         }
 8     }
 9     if(x+1<=mx)
10     {
11         if(map[x+1][y]<map[x][y])
12         {
13             down=snow(x+1,y)+1;
14         }
15     }
16     if(y-1>0)
17     {
18         if(map[x][y-1]<map[x][y])
19         {
20             left=snow(x,y-1)+1;
21         }
22     }
23     if(y+1<=my)
24     {
25         if(map[x][y+1]<map[x][y])
26         {
27             right=snow(x,y+1)+1;
28         }
29     }

看这个山坡的上下左右,如果比查找的山坡矮,则寻找这个山坡的最长路程。↑

 1     if(up<down)
 2     {
 3         up=down;
 4     }
 5     if(up<left)
 6     {
 7         up=left;
 8     }
 9     if(up<right)
10     {
11         up=right;
12     }
13     return up

然后比较上下左右的最长路程,看哪个最长,就是这个山坡到山脚的最长路程。↑

1     if(move[x][y]>0)
2     {
3         return move[x][y];
4     }

注意,如果这个山坡的最长路程已经确定,那么直接返回,可以节省时间。↑

完整代码见下方:

 1 #include<iostream>
 2 using namespace std;
 3 int map[113][113];
 4 int move[113][113];
 5 int mx,my;
 6 int snow(int x,int y)
 7 {
 8     if(move[x][y]>0)
 9     {
10         return move[x][y];
11     }
12     int up=0,down=0,left=0,right=0;
13     if(x-1>0)
14     {
15         if(map[x-1][y]<map[x][y])
16         {
17             up=snow(x-1,y)+1;
18         }
19     }
20     if(x+1<=mx)
21     {
22         if(map[x+1][y]<map[x][y])
23         {
24             down=snow(x+1,y)+1;
25         }
26     }
27     if(y-1>0)
28     {
29         if(map[x][y-1]<map[x][y])
30         {
31             left=snow(x,y-1)+1;
32         }
33     }
34     if(y+1<=my)
35     {
36         if(map[x][y+1]<map[x][y])
37         {
38             right=snow(x,y+1)+1;
39         }
40     }
41     if(up<down)
42     {
43         up=down;
44     }
45     if(up<left)
46     {
47         up=left;
48     }
49     if(up<right)
50     {
51         up=right;
52     }
53     return up;
54 }
55 int main()
56 {
57     int max1=0;
58     cin>>mx>>my;
59     for(int i=1;i<=mx;i++)
60     {
61         for(int j=1;j<=my;j++)
62         {
63             cin>>map[i][j];
64         }
65     }
66     for(int i=1;i<=mx;i++)
67     {
68         for(int j=1;j<=my;j++)
69         {
70             move[i][j]=snow(i,j); 
71             if(move[i][j]>max1)
72             {
73                 max1=move[i][j];
74             }
75         }
76     }
77     cout<<max1+1;
78 }

好吧,一道记忆化搜索~~~。

讲真我滑雪的时候才不会管怎么滑路程最长呢。

 

在暴风雨中低着头,是为了不让雨水模糊风雨后眼中的彩虹。

原文地址:https://www.cnblogs.com/DK-F/p/9442359.html