ACM Skiing问题

ACM Skiing问题

描述

      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         }
复制代码
 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         }
复制代码
 
 
分类: 动态规划
原文地址:https://www.cnblogs.com/Leo_wl/p/3179835.html