描述
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。
后面是下一组数据; - 输出
- 输出最长区域的长度。(例如上题的最长长度应该是25)。
- 本题解题思路:
- 苦思不得其解,后来看了解题报告才知道思路,即求出每个点的最长路径,找出最长路径,单个点的路径是通过动态规划的思想求出。当前点的最长路径等于上下左右中某一点的最长路径加1.
- C#代码如下:
-
1 static int[,] F = new int[5, 5];//保存已求解的每一点的最长长度,最大限度的减少计算量 2 static void Main(string[] args) 3 { 4 int[,] M = new int[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} }; 5 for (int i = 0; i < 5; i++) 6 { 7 for (int j = 0; j < 5; j++) 8 { 9 F[i, j] = 0; 10 Console.Write(M[i, j] + " "); 11 } 12 Console.WriteLine(); 13 } 14 int max = -1; 15 for (int i = 0; i < 5; i++) 16 { 17 for (int j = 0; j < 5; j++) 18 { 19 int length = FindLongest(M, i, j, 5, 1000); 20 if (length > max) 21 max = length; 22 } 23 } 24 Console.WriteLine(max); 25 Console.Read(); 26 27 } 28 /// <summary> 29 /// 求出最长路径的动态规划方式 30 /// </summary> 31 /// <param name="M">保存5*5矩阵</param> 32 /// <param name="m">开始求解点的横坐标</param> 33 /// <param name="n">开始求解点的纵坐标</param> 34 /// <param name="K">边界点,此处等于5</param> 35 /// <param name="value">上一点的值</param> 36 /// <returns>返回当前最长长度</returns> 37 public static int FindLongest(int[,] M, int m, int n, int K, int value) 38 { 39 //若超过边界或者当前点M[m,n]的值大于等于上一点的值value则返回。 40 if (m < 0 || n < 0 || m >= K || n >= K || M[m, n] >= value) 41 return 0; 42 43 if (F[m, n] > 0) 44 return F[m, n]; 45 //找出四点中最长路径+1 46 F[m, n] = Math.Max(Math.Max(FindLongest(M, m + 1, n, K, M[m, n]), FindLongest(M, m, n + 1, K, M[m, n])), Math.Max(FindLongest(M, m - 1, n, K, M[m, n]), FindLongest(M, m , n-1, K, M[m, n])))+1; 47 return F[m,n]; 48 49 }
版权所有,欢迎转载,但是转载请注明出处:潇一