滑雪问题
Description
Michael喜欢滑雪这并不奇怪,因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个区域中最长底滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。
Input 输入的第一行表示区域的行数n和列数m(1 <= n,m <= 100)。下面是n行,每行有m个整数,代表高度h,0<=h<=10000。
Output 输出最长区域的长度。
Sample Input 1
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 1
25
#include <iostream>
using namespace std;
const int MAX_ROWS = 100;
const int MAX_COLS = 100;
int directions[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};//定义方向数组 下(1,0)右(0,1)上(-1,0)左(0,-1)
bool isValid(int x, int y, int rows, int cols)//判断下一个要访问的是不是在区域内
{
if((x>=0)&&(x<rows)&&(y>=0)&&(y<cols))
return true;
else
return false;
}
int dfs(int matrix[MAX_ROWS][MAX_COLS], int (&dp)[MAX_ROWS][MAX_COLS], int x, int y, int rows, int cols)
{/*第一个二维数组matrix存储滑雪场的高度数据
* 第二个二维数组dp存储已经解决的子问题(二维数组 dp 作为缓存,其中 dp[i][j] 表示从点 (i, j) 出发的最长滑雪路径长度)
* 第三个是一个点(x,y)
* 第四个是滑雪场的长和宽
* */
if (dp[x][y] != -1)//如果 dp[x][y] 不等于 -1,表示已经计算过以 (x, y) 为起点的最长路径长度,直接返回该值。
{
return dp[x][y];
}
int maxLen = 1;
for (int i = 0; i < 4; ++i)
{//从当前点出发,尝试向四个方向滑行,选择比当前点低的点作为下一个滑行的目标。递归地计算以目标点为起点的最长路径长度,并更新最长路径长度。
int newX = x + directions[i][0];
int newY = y + directions[i][1];
if (isValid(newX, newY, rows, cols) && matrix[newX][newY] < matrix[x][y]) {
int len = 1 + dfs(matrix, dp, newX, newY, rows, cols);
maxLen = max(maxLen, len);//更新最大的长度
}
}
dp[x][y] = maxLen;//将计算结果存储在 dp[x][y] 中,以便后续查询时可以直接使用。
return maxLen;
}
int findLongestSkiingPath(int matrix[MAX_ROWS][MAX_COLS], int rows, int cols)
{
int dp[MAX_ROWS][MAX_COLS];
//dp存储的是,从当前点出发的最长滑雪路径长度
//此处使用动态规划的步骤
/*
1.定义子问题: 在这个问题中,子问题可以是从每个点 (i, j) 出发的最长滑雪路径长度。
2.找出子问题的解: 我们使用深度优先搜索 (DFS) 来递归地找到子问题的解,即从当前点出发的最长滑雪路径长度。
3.构建原问题的解: 在计算子问题的解的同时,我们使用一个数组 dp 来缓存已经计算过的结果,以便在需要时直接使用,避免重复计算。
*/
for (int i = 0; i < rows; ++i)//对用来缓存的dp二维数组赋初始值为-1
{
for (int j = 0; j < cols; ++j)
{
dp[i][j] = -1;
}
}
int maxLength = 0;//初始化最大的滑雪距离
for (int i = 0; i < rows; ++i)
{
for (int j = 0; j < cols; ++j)
{
int len = dfs(matrix, dp, i, j, rows, cols);//一个一个点读入
maxLength = max(maxLength, len);//更新最大的滑雪长度
}
}
return maxLength;
}
int main()
{
int n, m;
cin >> n >> m;
int matrix[MAX_ROWS][MAX_COLS];
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < m; ++j)
{
cin >> matrix[i][j];
}
}
int result = findLongestSkiingPath(matrix, n, m);
cout << result << endl;
return 0;
}