PmPen

----专注于Lamp技术
  管理

POJ 1088滑雪(动态规划)

Posted on 2010-12-07 21:42  PmPen  阅读(583)  评论(0编辑  收藏  举报
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 44052   Accepted: 15768

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 51 2 3 4 516 17 18 19 615 24 25 20 714 23 22 21 813 12 11 10 9

Sample Output

25

Source

此题通过枚举每一个坐标的最长路径,从而找出最长路径。在找坐标map[x][y]的最长路径是通过递归找出map[x-1][y](上),map[x+1][y](下),map[x][y-1](左),map[x][y+1](右)各自的最长路径;将MAX(map[x-1][y],map[x+1][y],map[x][y-1],map[x][y+1])+1即等于map[x][y]的最长路径。在对不同坐标递归时会多次访问到同一个map[i][j],做了大量重复操作,若用一个数组temp[][]保存访问到的map[i][j]的最长路径值,在下次访问到map[i][j]是直接返回temp[i][j]值,就大大提高效率【这就是动态规划】。
View Code
1 源代码:
2 #include<iostream>
3 usingnamespace std;
4 #define Max 100
5 int r,c;
6 int map[Max][Max],temp[Max][Max];
7 void Init()//初始化
8 {
9 int i,j;
10 for(i=0;i<r;i++)
11 for(j=0;j<c;j++)
12 cin>>map[i][j];
13 memset(temp,-1,sizeof(temp));
14 }
15 int DF(int x,int y)//动态规划
16 {
17 int max=0;
18 if(temp[x][y]>-1) //标记已被访问的状态,若再次访问则直接返回
19 return temp[x][y];
20 //递归调用找到(x,y)坐标四周最长路径,+1即等于(x,y)处的最长路径
21 if(x>0)
22 if(map[x][y]>map[x-1][y])
23 if(max<DF(x-1,y))
24 max=DF(x-1,y);
25 if(x<r-1)
26 if(map[x][y]>map[x+1][y])
27 if(max<DF(x+1,y))
28 max=DF(x+1,y);
29 if(y>0)
30 if(map[x][y]>map[x][y-1])
31 if(max<DF(x,y-1))
32 max=DF(x,y-1);
33 if(y<c-1)
34 if(map[x][y]>map[x][y+1])
35 if(max<DF(x,y+1))
36 max=DF(x,y+1);
37 temp[x][y]=max+1;
38 return temp[x][y];
39
40 }
41
42 void DO()//枚举所有map[i][j]
43 {
44 int i,j;
45 for(i=0;i<r;i++)
46 for(j=0;j<c;j++)
47 DF(i,j);
48 }
49
50
51
52 void Print()//找出最大路径输出
53 {
54 int i,j;
55 int max=0;
56 for(i=0;i<r;i++)
57 for(j=0;j<c;j++)
58 if(temp[i][j]>max)
59 max=temp[i][j];
60 cout<<max<<endl;
61
62 }
63 int main()
64 {
65 while(cin>>r>>c)
66 {
67 Init();
68 DO();
69 Print();
70 }
71 return0;
72 }