POJ 1088滑雪
链接:http://poj.org/problem?id=1088
Description
Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个区域中最长底滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子
一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-...-3-2-1更长。事实上,这是最长的一条。
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
简单的动规,可以是“我为人人型或者人人为我型”,下面解释一下我为人人型。
初始化以每个点为终点的最大长度为1,对高度进行排序,从小到大进行更新它周围的,分别判断它周围的的四个点,如果高度大于现在的高度且长度现在长度+1,则更新它的长度为现在长度+1.找到最大的长度即可。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #include <cmath> 5 using namespace std; 6 7 struct w 8 { 9 int x; 10 int y; 11 int val; 12 }k[110000]; 13 int cmp(w a,w b) 14 { 15 return a.val<b.val; 16 } 17 int main() 18 { 19 int h[110][110],ans[110][110],n,m; 20 while (cin>>n>>m) 21 { 22 for (int i=0;i<n;i++) 23 { 24 for (int j=0;j<m;j++) 25 { 26 cin>>h[i][j]; 27 k[i*m+j].x=i; 28 k[i*m+j].y=j; 29 k[i*m+j].val=h[i][j]; 30 ans[i][j]=1; 31 } 32 } 33 sort(k,k+n*m,cmp); 34 for (int i=0;i<n*m;i++) 35 { 36 int xi=k[i].x; 37 int yi=k[i].y; 38 if (xi-1>=0) 39 { 40 if (h[xi-1][yi]>h[xi][yi]) 41 { 42 ans[xi-1][yi]=max(ans[xi-1][yi],ans[xi][yi]+1); 43 } 44 } 45 if (xi+1<n) 46 { 47 if (h[xi+1][yi]>h[xi][yi]) 48 { 49 ans[xi+1][yi]=max(ans[xi+1][yi],ans[xi][yi]+1); 50 } 51 } 52 if (yi-1>=0) 53 { 54 if (h[xi][yi-1]>h[xi][yi]) 55 { 56 ans[xi][yi-1]=max(ans[xi][yi-1],ans[xi][yi]+1); 57 } 58 } 59 if (yi+1<m) 60 { 61 if (h[xi][yi+1]>h[xi][yi]) 62 { 63 ans[xi][yi+1]=max(ans[xi][yi+1],ans[xi][yi]+1); 64 } 65 } 66 } 67 int M=ans[0][0]; 68 for (int i=0;i<n;i++) 69 for (int j=0;j<m;j++) 70 if (ans[i][j]>M) 71 M=ans[i][j]; 72 cout <<M<<endl; 73 } 74 return 0; 75 }